Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
My goal is : Only allowed click to remove a rectangle if there is no rectangle in front of the target rectangle.
Maybe there is a solution to get a layer level from an object ? I have found nothing about this, im new to WPF. So if some can explain the solution or the way to think about this problem.
Code xaml.cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace WpfApp1
{
/// <summary>
/// Logique d'interaction pour MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
DispatcherTimer gameTimer = new DispatcherTimer();
List<Rectangle> removeThis = new List<Rectangle>();
int posX;
int posY;
int width;
int rectangleVariation;
int height;
Random rand = new Random();
Brush brush;
public MainWindow()
{
InitializeComponent();
Random rand = new Random();
int nbObjects = rand.Next(15,30);
for (int i = 0; i < nbObjects; i++)
{
brush = new SolidColorBrush(Color.FromRgb((byte)rand.Next(1, 255), (byte)rand.Next(1, 255), (byte)rand.Next(1, 255)));
posX = rand.Next(15, 700);
posY = rand.Next(50, 250);
rectangleVariation = rand.Next(0, 2);
if (rectangleVariation == 0)
{
width = 200;
height = 50;
}
else
{
width = 50;
height = 200;
}
Rectangle rectangle = new Rectangle
{
Tag = "rectangle",
Height = height,
Width = width,
Stroke = Brushes.Black,
StrokeThickness = 1,
Fill = brush
};
Canvas.SetLeft(rectangle, posX);
Canvas.SetTop(rectangle, posY);
MyCanvas.Children.Add(rectangle);
}
}
private void ClickOnCanvas(object sender, MouseButtonEventArgs e)
{
if (e.OriginalSource is Rectangle)
{
Rectangle rectangle = (Rectangle)e.OriginalSource;
MyCanvas.Children.Remove(rectangle);
}
}
}
}
Code xaml file :
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Canvas Name="MyCanvas" MouseLeftButtonDown="ClickOnCanvas" Background="DarkGray">
</Canvas>
</Window>
You should first determine whether the clicked Rectangle intersects with any other Rectangle elements and if it does, you could determine whether it's in top of all of them by looking at the index in the Canvas's Children collection.
The Rect type has an IntersectsWith method that you can use. Something like this:
private void ClickOnCanvas(object sender, MouseButtonEventArgs e)
{
if (e.OriginalSource is Rectangle)
{
Rectangle clickedRectangle = (Rectangle)e.OriginalSource;
Rect clickedRect = new Rect()
{
Location = new Point(Canvas.GetLeft(clickedRectangle), Canvas.GetTop(clickedRectangle)),
Size = new Size(clickedRectangle.Width, clickedRectangle.Height)
};
for (int i = 0; i < MyCanvas.Children.Count; i++)
{
if (MyCanvas.Children[i] is Rectangle rectangle && rectangle != clickedRectangle)
{
Rect rect = new Rect()
{
Location = new Point(Canvas.GetLeft(rectangle), Canvas.GetTop(rectangle)),
Size = new Size(rectangle.Width, rectangle.Height)
};
if (clickedRect.IntersectsWith(rect) && MyCanvas.Children.IndexOf(clickedRectangle) < i)
return;
}
}
MyCanvas.Children.Remove(clickedRectangle);
}
}
Related
This is my first time posting, so be easy on me...
There are definitely posts that show how to connect lines to blocks, but this one is slightly different. The grids are placed on the canvas dynamically. I want a line to connect the grid from where the button is pressed to the new grid that's placed on the canvas. However the below code doesn't work. I've struggled with this one for a very long time.
Solely by accident I discovered a Messagebox thrown in the button event handler will allow it to work. I figured this was from threads running at different times, but after messing with task.delay/thread.sleep/async/await I can't find the solution.
I'm using custom classes because this is a stripped down version of the larger program, I wanted to have similar functionality in my example to reflect possible errors but leave out the unnecessary pieces.
I'm using this as a last resort, thank you in advance for any help you can provide. First the CS code
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Grid1 g = myCanvas.CreateGrid();
ContentControl1 cc = myCanvas.CreateCC();
Button1 b = myCanvas.CreateButton1();
Grid1.SetColumn(cc, 0);
Grid1.SetRow(cc, 0);
Grid1.SetColumn(b, 1);
Grid1.SetRow(b, 1);
g.Children.Add(cc);
g.Children.Add(b);
Canvas1.SetLeft(g, 500);
Canvas1.SetTop(g, 5);
myCanvas.Children.Add(g);
}
}
public class Button1 : Button
{
protected override void OnClick()
{
Grid1 old_g = (Grid1)VisualTreeHelper.GetParent(this as DependencyObject);
Canvas1 cnv = (Canvas1)VisualTreeHelper.GetParent(old_g as DependencyObject);
Grid1 g = cnv.CreateGrid();
ContentControl1 cc = cnv.CreateCC();
Button1 b = cnv.CreateButton1();
Grid1.SetColumn(cc, 0);
Grid1.SetRow(cc, 0);
Grid1.SetColumn(b, 1);
Grid1.SetRow(b, 1);
g.Children.Add(cc);
g.Children.Add(b);
Canvas1.SetLeft(g, 500);
Canvas1.SetTop(g, cnv.Children.Count * 120);
cnv.Children.Add(g);
cnv.ConnectGrids(old_g, g);
}
}
public class Canvas1 : Canvas
{
public Grid1 CreateGrid()
{
Grid1 g = new Grid1() { Width = 100, Height = 20, Background = Brushes.White };
g.HorizontalAlignment = HorizontalAlignment.Center;
g.VerticalAlignment = VerticalAlignment.Center;
g.ShowGridLines = false;
ColumnDefinition colDef1 = new ColumnDefinition();
ColumnDefinition colDef2 = new ColumnDefinition() { Width = new GridLength(20) };
g.ColumnDefinitions.Add(colDef1);
g.ColumnDefinitions.Add(colDef2);
RowDefinition rowDef1 = new RowDefinition();
g.RowDefinitions.Add(rowDef1);
return g;
}
public ContentControl1 CreateCC()
{
ContentControl1 cc = new ContentControl1()
{
VerticalContentAlignment = VerticalAlignment.Stretch,
HorizontalContentAlignment = HorizontalAlignment.Stretch,
BorderBrush = Brushes.BlueViolet,
};
return cc;
}
public Button1 CreateButton1()
{
Button1 b = new Button1()
{
VerticalContentAlignment = VerticalAlignment.Stretch,
HorizontalContentAlignment = HorizontalAlignment.Stretch,
BorderBrush = Brushes.Red
};
return b;
}
public void ConnectGrids(Grid1 g1, Grid1 g2)
{
Canvas1 cnv = (Canvas1)VisualTreeHelper.GetParent(g1 as DependencyObject);
Transform transform1 = (Transform)g1.TransformToVisual(cnv as Visual);
Transform transform2 = (Transform)g2.TransformToVisual(cnv as Visual);
Point StartPoint1 = transform1.Transform(new Point(g1.Width, g1.Height / 2.0));
Point EndPoint1 = transform2.Transform(new Point(g2.Width, g2.Height / 2.0));
var lineGeometry = new LineGeometry()
{
StartPoint = StartPoint1,
EndPoint = EndPoint1
};
var path = new Path()
{
Data = lineGeometry,
Stroke = new SolidColorBrush(Colors.Black),
};
cnv.Children.Add(path);
}
}
public class ContentControl1 : ContentControl
{
}
public class Grid1 : Grid
{
}
}
then the xaml:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local ="clr-namespace:WpfApplication1"
Title="MainWindow" Height="1000" Width="1000">
<DockPanel>
<Button DockPanel.Dock="Top" Width="100" Height="20" Content="Start" Click="Button_Click"/>
<ScrollViewer HorizontalScrollBarVisibility="Visible" Width="901" x:Name="_scrollViewer" Margin="0,5,0,25">
<local:Canvas1 Background="Gray" Height="1000" Width="1000" x:Name="myCanvas"/>
</ScrollViewer>
</DockPanel>
</Window>
How can I successfully connect the grid with the path?
I love that I solved this/hate that I have to answer my own dumb question...
Sooo simple. UpdateLayout(). The objects don't change location until it has been rendered, so the line was going to its old location.
I've got two images, one of them I'll create using Graphics (a simple circle/ellipse).
Now I want to remove a part of the circle using another image. It should support removing alpha values too.
I hope the link works, if not please write it into comments & I'll fix it.
Thanks for any advice
EDIT:
Image 2 does not really have any border, it is just to show the frame size...
The following will do:
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace WpfApplication4
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
var image1 = new BitmapImage(new Uri("1.png", UriKind.Relative));
var image2 = new BitmapImage(new Uri("2.png", UriKind.Relative));
var bitmap1 = BitmapFactory.ConvertToPbgra32Format(image1);
var bitmap2 = BitmapFactory.ConvertToPbgra32Format(image2);
var width = 256;
var height = 256;
var bitmap3 = BitmapFactory.New(width, height);
var transparent = Color.FromArgb(0, 0, 0, 0);
for (var y = 0; y < height; y++)
{
for (var x = 0; x < width; x++)
{
var color1 = bitmap1.GetPixel(x, y);
var color2 = bitmap2.GetPixel(x, y);
Color color3;
if (color1.Equals(transparent))
{
color3 = transparent;
}
else
{
if (color2.Equals(transparent))
{
color3 = color1;
}
else
{
color3 = transparent;
}
}
bitmap3.SetPixel(x, y, color3);
}
}
Image1.Source = bitmap3;
}
}
}
I've used https://www.nuget.org/packages/WriteableBitmapEx/ to make things simpler, be careful about having 32-bit PNG as well as what is a transparent color because in WPF it is a transparent white in fact.
You should be able to translate that to Forms easily if this is what you're using, with this https://msdn.microsoft.com/en-us/library/system.drawing.bitmap%28v=vs.110%29.aspx.
EDIT : you could have used an opacity mask but since pic.2 does not its outer dark, it wouldn't have worked.
Finally, I wrote the code by myself. This is it:
public static Bitmap RemovePart(Bitmap source, Bitmap toRemove)
{
Color c1, c2, c3;
c3 = Color.FromArgb(0, 0, 0, 0);
for (int x = 0; x < source.Width; x++)
{
for (int y = 0; y < source.Height; y++)
{
c1 = source.GetPixel(x, y);
c2 = toRemove.GetPixel(x, y);
if (c2 != c3)
{
source.SetPixel(x, y, Color.FromArgb(c2.A, c1));
}
}
}
}
I have a user control which moves with my finger movement.The user control has its own manipulation delta set.
My problem is , when My finger is on the user control and I am trying to move it up , I am having lag because it is not moving up with my finger.
The user control appears when I long tap on my screen , the location of the user control is whereever my finger is pressed . It moves with my finger whereever I move my finger , but once my finger goes on the user control I am not having smooth movements .
Any help would be appreciated.
The XAML is
<Page x:Name="page1"
x:Class="controlMagnifier.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:controlMagnifier"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid x:Name="ParentGrid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" PointerReleased="ParentGrid_OnPointerReleased" >
<Canvas x:Name="InkPresenter" Height="auto" Width="auto">
<Image Stretch="None" x:Name="image2" >
<Image.Source >
<BitmapImage UriSource="/Assets/wallpaper.jpg" />
</Image.Source>
</Image>
</Canvas>
<local:MagnifierUsercontrol x:Name="MagnifyTip" Visibility="Collapsed" ManipulationDelta="MagnifyTip_ManipulationDelta" ManipulationMode="All" >
<local:MagnifierUsercontrol.RenderTransform>
<CompositeTransform/>
</local:MagnifierUsercontrol.RenderTransform>
</local:MagnifierUsercontrol>
</Grid>
</Page>
The CS Code Is
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Shapes;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using System.Diagnostics;
using Windows.UI.Popups;
using Windows.UI.Input;
using Windows.Storage;
using Windows.UI.Xaml.Media.Imaging;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace controlMagnifier
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public const int XAxis = 105;
public const int YAxis = 270;
public Thickness margin;
public WriteableBitmap CurrentBitmapObj, CurrentCroppedImage = null;
public MainPage()
{
this.InitializeComponent();
ParentGrid.Holding += Grid_Holding;
image2.PointerMoved += InkCanvas_PointerMoved;
image2.PointerReleased += ParentGrid_OnPointerReleased;
image2.CacheMode=new BitmapCache();
StoreCrrentImage();
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Grid_Holding(object sender, HoldingRoutedEventArgs e)
{
//Point p;
try
{
Point p = e.GetPosition(ParentGrid);
double height = MagnifyTip.Height;
double width = MagnifyTip.Width;
margin = MagnifyTip.Margin;
margin.Left = p.X - XAxis;
margin.Right = p.Y - YAxis;
MagnifyTip.Margin = margin;
// MagnifyTip.Margin = new Thickness(p.X - XAxis, p.Y - YAxis, 0, 0);
MagnifyTip.Visibility = Visibility.Visible;
}
catch (Exception)
{
throw;
}
}
private void InkCanvas_PointerMoved(object sender, PointerRoutedEventArgs e)
{
try
{
PointerPoint pt = e.GetCurrentPoint(image2);
Point currentContactPt = pt.Position;
double xValue = currentContactPt.X;
double yValue = currentContactPt.Y;
// MagnifyTip.
double height = MagnifyTip.Height;
double width = MagnifyTip.Width;
MagnifyTip.image1.ImageSource = CropBitmap(currentContactPt);
MagnifyTip.Margin = new Thickness(xValue - XAxis, yValue - YAxis, 0, 0);
}
catch (Exception)
{
throw;
}
finally
{e.Handled = true;}
}
private async void StoreCrrentImage()
{
try
{
StorageFile storageFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/wallpaper.jpg", UriKind.RelativeOrAbsolute));
using (
Windows.Storage.Streams.IRandomAccessStream fileStream =
await storageFile.OpenAsync(FileAccessMode.Read))
{
BitmapImage bitmapImage = new BitmapImage();
await bitmapImage.SetSourceAsync(fileStream);
WriteableBitmap writeableBitmap =
new WriteableBitmap(bitmapImage.PixelWidth, bitmapImage.PixelHeight);
fileStream.Seek(0);
await writeableBitmap.SetSourceAsync(fileStream);
CurrentBitmapObj = writeableBitmap;
writeableBitmap.Invalidate();
}
}
catch (Exception )
{
throw;
}
finally
{}
}
/// <summary>
/// This method crops the image by accepting x and y as Arguments
/// </summary>
/// <param name="point"></param>
/// <returns>Cropped Image</returns>
private WriteableBitmap CropBitmap(Point point)
{
try
{
CurrentCroppedImage = CurrentBitmapObj.Crop(Convert.ToInt32(point.X), Convert.ToInt32(point.Y), 100, 100);
// var resized = CurrentCroppedImage.Resize(200, 300, WriteableBitmapExtensions.Interpolation.Bilinear);
}
catch (Exception)
{
throw;
}
return CurrentCroppedImage;
}
private void MagnifyTip_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
Point p;
p.X = e.Delta.Translation.X;
p.Y = e.Delta.Translation.Y;
var Dragme = (CompositeTransform)MagnifyTip.RenderTransform;
Dragme.TranslateX += p.X;
Dragme.TranslateY += p.Y;
// MagnifyTip.controlCanvas.SetValue(Canvas.SetLeft, p.X);
}
private void ParentGrid_OnPointerReleased(object sender, PointerRoutedEventArgs e)
{
MagnifyTip.Visibility = Visibility.Collapsed;
// throw new NotImplementedException();
}
}
}
The user control looks like
If you want to avoid the lag which is intentionally implemented in ManipulationDelta to distinguish it from Tap, use PointerMove instead.
I have answered similar question here.
I have a matrix with an uneven number of columns per row. The number of columns decreases with increasing rows. Now there is a curve drawn on top of the matrix.
A requirement is, that the curve has to be completely within the matrix.
The picture is a matrix where the curve leaves the boundaries of the matrix. This is what I have to fix.
The algorithm that calculates the curve is not aware of the size of the matrix.
The question is: What is the best way to fulfill this requirement?
Will the algorithm that calculates the curve have to change to be aware of the matrix dimensions?
Or can I change the curve afterwards to "live" inside the matrix?
What would you recommend?
The expected curve would look like this:
I added blue dots to the points that make up the polyline. The little black dots on the line represent calculated points based on linear interpolation. Each of these calculated Points can be tested to determine whether they are inside or outside of the matrix. The actual matrix has more columns and rows but displaying it does not add to the clarity of the task at hand or the possible approach to solve it.
I created a little demo:
MainWindows.xaml
<Window x:Class="InsideMatrix.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:InsideMatrix"
Title="MainWindow" Height="250" Width="525" x:Name="Main">
<Grid>
<local:Matrix/>
<Polyline Stroke="Red" StrokeThickness="3" Points="{Binding Curve, ElementName=Main}" Visibility="Visible"/>
</Grid>
</Window>
MainWindow.xaml.cs
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Media;
namespace InsideMatrix
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
private PointCollection curve;
public MainWindow()
{
InitializeComponent();
if (!DesignerProperties.GetIsInDesignMode(this))
{
this.Curve = this.CalculateCurve();
}
}
private PointCollection CalculateCurve()
{
// This is just a stub for an algorith that will calculate a curve
return new PointCollection()
{
new Point(57, 24),
new Point(114, 48),
new Point(171, 72),
new Point(228, 96),
new Point(456, 153)
};
}
public PointCollection Curve
{
get { return this.curve; }
set
{
this.curve = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Matrix.xaml
<UserControl x:Class="InsideMatrix.Matrix"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:insideMatrix="clr-namespace:InsideMatrix"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
</Grid>
</UserControl>
Matrix.xaml.cs
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace InsideMatrix
{
public partial class Matrix : UserControl
{
private int width = 57;
private int height = 24;
private int[] cellsPerRow = { 7, 7, 4, 4, 2, 2 };
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
if (DesignerProperties.GetIsInDesignMode(this)) return;
Pen pen = new Pen(new SolidColorBrush(Colors.Black), 1);
int row = 0;
foreach (var cells in cellsPerRow)
{
row++;
for (int column = 7; column > 7 - cells; column--)
{
drawingContext.DrawRectangle(new SolidColorBrush(Colors.Transparent), pen, new Rect(column * width, row * height, width, height));
}
}
}
}
}
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I hope to develop a program to get a kinect depth image and convert it into 3D point cloud as my final year project.
I have to write a program to save those depth images into bin directory of the project. But I'm unable to convert those images to 3d point cloud.
If anyone has an idea about how to implement this or any working projects for that please help me.
I suggest that you check out PCL library. It's open project for 3D point cloud processing, and it's quite well-documented. There are many tutorials, but for your task you should take look at:
Kinect OpenNI tutorial (fast access to point cloud using PCL and OpenNI library)
See i-programmer for how to make a point-cloud. And if you just want to make one and not understand it(which I strongly don't advise), here is the code:
XAML:
<Window x:Class="PointCloudWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Point Cloud" Height="653" Width="993" Background="Black" Loaded="Window_Loaded">
<Grid Height="1130" Width="1626">
<Canvas Height="611" HorizontalAlignment="Left" Name="canvas1" VerticalAlignment="Top" Width="967" Background="Black" />
</Grid>
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Media3D;
using Microsoft.Kinect;
namespace PointCloudWPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
GeometryModel3D[] points = new GeometryModel3D[320 * 240];
int s = 4;
KinectSensor sensor;
public MainWindow()
{
InitializeComponent();
}
void DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
{
DepthImageFrame imageFrame = e.OpenDepthImageFrame();
if (imageFrame != null)
{
short[] pixelData = new short[imageFrame.PixelDataLength];
imageFrame.CopyPixelDataTo(pixelData);
int temp = 0;
int i = 0;
for (int y = 0; y < 240; y += s)
for (int x = 0; x < 320; x += s)
{
temp = ((ushort)pixelData[x + y * 320]) >> 3;
((TranslateTransform3D)points[i].Transform).OffsetZ = temp;
i++;
}
}
}
private GeometryModel3D Triangle(double x, double y, double s, SolidColorBrush color)
{
Point3DCollection corners = new Point3DCollection();
corners.Add(new Point3D(x, y, 0));
corners.Add(new Point3D(x, y + s, 0));
corners.Add(new Point3D(x + s, y + s, 0));
Int32Collection Triangles = new Int32Collection();
Triangles.Add(0);
Triangles.Add(1);
Triangles.Add(2);
MeshGeometry3D tmesh = new MeshGeometry3D();
tmesh.Positions = corners;
tmesh.TriangleIndices = Triangles;
tmesh.Normals.Add(new Vector3D(0, 0, -1));
GeometryModel3D msheet = new GeometryModel3D();
msheet.Geometry = tmesh;
msheet.Material = new DiffuseMaterial(color);
return msheet;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
DirectionalLight DirLight1 = new DirectionalLight();
DirLight1.Color = Colors.White;
DirLight1.Direction = new Vector3D(1, 1, 1);
PerspectiveCamera Camera1 = new PerspectiveCamera();
Camera1.FarPlaneDistance = 8000;
Camera1.NearPlaneDistance = 100;
Camera1.FieldOfView = 10;
Camera1.Position = new Point3D(160, 120, -1000);
Camera1.LookDirection = new Vector3D(0, 0, 1);
Camera1.UpDirection = new Vector3D(0, -1, 0);
Model3DGroup modelGroup = new Model3DGroup();
int i = 0;
for (int y = 0; y < 240; y += s)
{
for (int x = 0; x < 320; x += s)
{
points[i] = Triangle(x, y, s, new SolidColorBrush(Colors.White));
// points[i]=MCube(x,y);
points[i].Transform = new TranslateTransform3D(0, 0, 0);
modelGroup.Children.Add(points[i]);
i++;
}
}
modelGroup.Children.Add(DirLight1);
ModelVisual3D modelsVisual = new ModelVisual3D();
modelsVisual.Content = modelGroup;
Viewport3D myViewport = new Viewport3D();
myViewport.IsHitTestVisible = false;
myViewport.Camera = Camera1;
myViewport.Children.Add(modelsVisual);
canvas1.Children.Add(myViewport);
myViewport.Height = canvas1.Height;
myViewport.Width = canvas1.Width;
Canvas.SetTop(myViewport, 0);
Canvas.SetLeft(myViewport, 0);
sensor = KinectSensor.KinectSensors[0];
sensor.SkeletonStream.Enable();
sensor.DepthStream.Enable(DepthImageFormat.Resolution320x240Fps30);
sensor.DepthFrameReady += DepthFrameReady;
sensor.Start();
}
}
}