I am building an application where I have to draw my own figures on a Canvas. Right now I am doing it like this:
PathFigure figure = new PathFigure() { StartPoint = new Point(0, TurboHeight / turboSizeFactor * turboSchaufelFactor), IsClosed = true};
LineSegment seg = new LineSegment() { Point = new Point(turboWidth, TurboHeight / turboSizeFactor * turboSchaufelFactor) };
figure.Segments.Add(seg);
seg = new LineSegment(){Point=new Point(turboWidth*0.85, 0)};
figure.Segments.Add(seg);
seg = new LineSegment() { Point = new Point(turboWidth * 0.15, 0) };
figure.Segments.Add(seg);
PathGeometry geo = new PathGeometry();
geo.Figures.Add(figure);
Path path = new Path() { Data = geo, Stroke = Brushes.Black, StrokeThickness = 1, SnapsToDevicePixels = true, Fill = Brushes.LightGray};
CnvMain.Children.Add(path);
Is this the way to do it or is there a simpler way. I mean its a lot of objects I am creating for a few lines on a canvas.
Thanks.
Seems to me like you're not wasting too much. Only thing I would do is not store all the intermediate results in variables that you reuse... E.g.:
PathFigure figure = new PathFigure()
{
StartPoint = new Point(0, TurboHeight / turboSizeFactor * turboSchaufelFactor),
IsClosed = true
};
figure.Segments.Add(new LineSegment() { Point = new Point(turboWidth, TurboHeight / turboSizeFactor * turboSchaufelFactor) });
figure.Segments.Add(new LineSegment() { Point = new Point(turboWidth * 0.85, 0) });
figure.Segments.Add(new LineSegment() { Point = new Point(turboWidth * 0.15, 0) });
PathGeometry geo = new PathGeometry();
geo.Figures.Add(figure);
Path path = new Path() { Data = geo, Stroke = Brushes.Black, StrokeThickness = 1, SnapsToDevicePixels = true, Fill = Brushes.LightGray };
CnvMain.Children.Add(path);
You could of course put the whole stuff in a method or put the points in an array, but for such a small function that seems just silly... if you have more points it might make sense.
Related
Right now I am using Viewport3D in which I am drawing all 3D shapes but I also want to draw arc, point and lines in Viewport3D. Can anyone help me with this?
private Viewport2DVisual3D ArcModel;
private Model3DGroup group;
MeshGeometry3D testGeometry = new MeshGeometry3D();
PathFigure pthFigure = new PathFigure();
pthFigure.StartPoint = new Point(1, 1);
ArcSegment arcSeg = new ArcSegment();
arcSeg.Point = new Point(30, 30);
arcSeg.Size = new Size(20, 20);
arcSeg.IsLargeArc = true;
arcSeg.SweepDirection = SweepDirection.Counterclockwise;
//arcSeg.RotationAngle = 30;
PathSegmentCollection myPathSegmentCollection = new PathSegmentCollection();
myPathSegmentCollection.Add(arcSeg);
pthFigure.Segments = myPathSegmentCollection;
PathFigureCollection pthFigureCollection = new PathFigureCollection();
pthFigureCollection.Add(pthFigure);
PathGeometry pthGeometry = new PathGeometry();
pthGeometry.Figures = pthFigureCollection;
Path arcPath = new Path();
arcPath.Stroke = new SolidColorBrush(Colors.Violet);
arcPath.StrokeThickness = 1;
arcPath.Data = pthGeometry;
//arcPath.Fill = new SolidColorBrush(Colors.Yellow);
//Children.Add(arcPath);
Point3DCollection myPoint3DCollection = new Point3DCollection();
myPoint3DCollection.Add(new Point3D(0, 0, 0));
myPoint3DCollection.Add(new Point3D(0, 0, 2));
myPoint3DCollection.Add(new Point3D(0, 2, 0));
myPoint3DCollection.Add(new Point3D(0, 2, 2));
testGeometry.Positions = myPoint3DCollection;
PointCollection myPointCollection = new PointCollection();
myPointCollection.Add(new Point(0, 1));
myPointCollection.Add(new Point(1, 1));
myPointCollection.Add(new Point(0, 0));
myPointCollection.Add(new Point(1, 0));
testGeometry.TextureCoordinates = myPointCollection;
Int32Collection triangleIndicesCollection = new Int32Collection();
triangleIndicesCollection.Add(0);
triangleIndicesCollection.Add(1);
triangleIndicesCollection.Add(2);
triangleIndicesCollection.Add(2);
triangleIndicesCollection.Add(1);
triangleIndicesCollection.Add(3);
testGeometry.TriangleIndices = triangleIndicesCollection;
DiffuseMaterial myDiffuseMaterial = new DiffuseMaterial(Brushes.White);
Viewport2DVisual3D.SetIsVisualHostMaterial(myDiffuseMaterial, true);
ArcModel = new Viewport2DVisual3D();
ArcModel.Material = myDiffuseMaterial;
ArcModel.Geometry = testGeometry;
//group.Children.Add(ArcModel.Geometry);
ArcModel.Visual = arcPath;
ArcGeomodel = new GeometryModel3D(ArcModel.Geometry, myDiffuseMaterial);
ArcGeomodel.Transform = new Transform3DGroup();
group.Children.Add(ArcGeomodel);
viewport.Children.Add(ArcModel);
I am drawing this arc using path geometry and adding it into Viewport2DVisual3D but its not getting displayed...
what I am missing here ...please suggest any solution
Finally got what I was missing.I was missing to add transformation and rotation to it
following is the code
Transform3DGroup myTransform3DGroup = new Transform3DGroup();
RotateTransform3D rotateTransform = new RotateTransform3D()
{
Rotation = new AxisAngleRotation3D
{
Angle = 40,
Axis = new Vector3D(0, 1, 0)
}
};
myTransform3DGroup.Children.Add(rotateTransform);
ArcModel.Transform = myTransform3DGroup;
ArcModel.Material = myDiffuseMaterial;
ArcModel.Geometry = testGeometry;
ArcModel.Visual = arcPath;
viewport.Children.Add(ArcModel);
Hope this will help someone!
I want to draw a simple Path which uses RenderedGeometry of a Polygon as Data.
Polygon polygon = new Polygon();
polygon.Points = new PointCollection { new Point(0, 0), new Point(0, 100), new Point(150, 150) };
var path = new Path
{
Data = polygon.RenderedGeometry,
Stroke = Brushes.LightBlue,
StrokeThickness = 2,
Fill = Brushes.Green,
Opacity = 0.5
};
Panel.SetZIndex(path, 2);
canvas.Children.Add(path);
However my Canvas does not display anything.
You should force the geometry to be rendered before you it to the Canvas. You can do this by calling the Arrange and Measure methods of the Polygon:
Polygon polygon = new Polygon();
polygon.Points = new PointCollection { new Point(0, 0), new Point(0, 100), new Point(150, 150) };
polygon.Arrange(new Rect(canvas.RenderSize));
polygon.Measure(canvas.RenderSize);
var path = new Path
{
Data = polygon.RenderedGeometry,
Stroke = Brushes.LightBlue,
StrokeThickness = 2,
Fill = Brushes.Green,
Opacity = 0.5
};
Panel.SetZIndex(path, 2);
canvas.Children.Add(path);
You shouldn't be using a Polygon element to define the Geometry of a Path.
Instead directly create a PathGeometry like this:
var figure = new PathFigure
{
StartPoint = new Point(0, 0),
IsClosed = true
};
figure.Segments.Add(new PolyLineSegment
{
Points = new PointCollection { new Point(0, 100), new Point(150, 150) },
IsStroked = true
});
var geometry = new PathGeometry();
geometry.Figures.Add(figure);
var path = new Path
{
Data = geometry,
Stroke = Brushes.LightBlue,
StrokeThickness = 2,
Fill = Brushes.Green,
Opacity = 0.5
};
Or directly create a Geometry from a string using Path Markup Syntax:
var path = new Path
{
Data = Geometry.Parse("M0,0 L0,100 150,150Z"),
Stroke = Brushes.LightBlue,
StrokeThickness = 2,
Fill = Brushes.Green,
Opacity = 0.5
};
I want to draw the Shape as in the image. I have drawn half circle using Arc Segment, Now I want to draw Quarter circle, or A Sector, But I am unable to draw it.
I used this code to draw Arc, I tried to change the size, and the angle is also not working.
What should I do to draw Quarter circle / Sector ?? Code I used to draw Arc is :
PathFigure pthFigure1 = new PathFigure();
pthFigure1.StartPoint = new Point(50, 60);// starting cordinates of arcs
ArcSegment arcSeg1 = new ArcSegment();
arcSeg1.Point = new Point(100, 82); // ending cordinates of arcs
arcSeg1.Size = new Size(10, 10);
arcSeg1.IsLargeArc = false;
arcSeg1.SweepDirection = SweepDirection.Clockwise;
arcSeg1.RotationAngle = 90;
PathSegmentCollection myPathSegmentCollection1 = new PathSegmentCollection();
myPathSegmentCollection1.Add(arcSeg1);
pthFigure1.Segments = myPathSegmentCollection1;
PathFigureCollection pthFigureCollection1 = new PathFigureCollection();
pthFigureCollection1.Add(pthFigure1);
PathGeometry pthGeometry1 = new PathGeometry();
pthGeometry1.Figures = pthFigureCollection1;
System.Windows.Shapes.Path arcPath1 = new System.Windows.Shapes.Path();
arcPath1.Data = pthGeometry1;
arcPath1.Fill = new SolidColorBrush(Color.FromArgb(255, 255, 23, 0));
this.LayoutRoot.Children.Add(arcPath1);
With minimum changes to your code (/**/ signifies changed or added lines).
PathFigure pthFigure1 = new PathFigure();
/**/ pthFigure1.StartPoint = new Point(0, 100);// starting cordinates of arcs
ArcSegment arcSeg1 = new ArcSegment();
/**/ arcSeg1.Point = new Point(100, 0); // ending cordinates of arcs
/**/ arcSeg1.Size = new Size(100, 100);
arcSeg1.IsLargeArc = false;
arcSeg1.SweepDirection = SweepDirection.Clockwise;
/**/ LineSegment lineSeg = new LineSegment();
/**/ lineSeg.Point = new Point(100,100);
PathSegmentCollection myPathSegmentCollection1 = new PathSegmentCollection();
myPathSegmentCollection1.Add(arcSeg1);
/**/ myPathSegmentCollection1.Add(lineSeg);
pthFigure1.Segments = myPathSegmentCollection1;
PathFigureCollection pthFigureCollection1 = new PathFigureCollection();
pthFigureCollection1.Add(pthFigure1);
...
It seems that you missinterpret the meaning of ArcSegment.RotationAngle.
The math of it:
So, Basically I'm trying to draw a line between the center of 2 ellipses
And I think this should do it:
Path myPath = new Path();
myPath.Stroke = System.Windows.Media.Brushes.Black;
myPath.StrokeThickness = 4;
myPath.HorizontalAlignment = HorizontalAlignment.Left;
myPath.VerticalAlignment = VerticalAlignment.Center;
EllipseGeometry myEllipseGeometry = new EllipseGeometry();
myEllipseGeometry.Center = new System.Windows.Point((xQuard * 10) + 100, yQuard * 10);
myEllipseGeometry.RadiusX = 2;
myEllipseGeometry.RadiusY = 2;
myPath.Data = myEllipseGeometry;
GraphPanel.Children.Add(myPath);
//if it's not the first point...
if (prevA != 0.0)
{
Path iLine = new Path();
iLine.Stroke = Brushes.Black;
iLine.StrokeThickness = 4;
iLine.HorizontalAlignment = HorizontalAlignment.Left;
myPath.VerticalAlignment = VerticalAlignment.Center;
LineGeometry iLineGeometry = new LineGeometry();
iLineGeometry.StartPoint = myEllipseGeometry.Center;
iLineGeometry.EndPoint = new System.Windows.Point(prevA, prevB);
iLine.Data = iLineGeometry;
GraphPanel.Children.Add(iLine);
}
//Set the previous point(s)
prevA = (xQuard * 10) + 100;
prevB = yQuard * 10;
Now as you can see, I've set the Line's StartPoint = to the first ellipse start point
And Yet....
Why is the Line's start point in the picture not the center of the point on the left?
I think you mean iLine.VerticalAlignment instead of myPath.VerticalAlignment the second time, right?
I have two UIElements(i.e. rectangles) in Canvas and their coordinates. How can I connect them with arc in code behind?
No need to get an exact hit on the rectangles (or other objects): make sure the Z ordering is correct. arc.SetValue(Canvas.ZIndex, -1) will push it to the background. If you want a perpendicular hit, you'll need to break out the algebra :/
For the arc: (see http://msdn.microsoft.com/en-us/library/ms751808.aspx), it needs to be contained in a PathFigure.
Edit: this shows two connected rectangles. The line simple runs between the two centers. The arc starts on one center (the pathFigure startpoint), first argument is the center of the second object.
r1 = new Rectangle();
r1.Margin = new Thickness(50, 50, 0, 0);
r1.VerticalAlignment = System.Windows.VerticalAlignment.Top;
r1.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
r1.Height = 50;
r1.Width= 50;
r1.Fill = new SolidColorBrush(Colors.Red);
r2 = new Rectangle();
r2.Width = 50;
r2.Height = 50;
r2.Fill = new SolidColorBrush(Colors.Blue);
r2.Margin = new Thickness(350, 450, 0, 0);
r2.VerticalAlignment = System.Windows.VerticalAlignment.Top;
r2.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
l = new Line();
l.X1 = 75;
l.Y1 = 75;
l.X2 = 375;
l.Y2 = 475;
l.Fill = new SolidColorBrush(Colors.Purple);
l.Stroke = new SolidColorBrush(Colors.Purple);
l.StrokeThickness = 2;
l.SetValue(Canvas.ZIndexProperty, -1);
PathGeometry myPathGeometry = new PathGeometry();
// Create a figure.
PathFigure pathFigure1 = new PathFigure();
pathFigure1.StartPoint = new Point(75, 75);
pathFigure1.Segments.Add(
new ArcSegment(
new Point(375, 475),
new Size(50, 50),
45,
true, /* IsLargeArc */
SweepDirection.Clockwise,
true /* IsStroked */ ));
myPathGeometry.Figures.Add(pathFigure1);
// Display the PathGeometry.
Path myPath = new Path();
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myPathGeometry;
myPath.SetValue(Canvas.ZIndexProperty, -1);
LayoutRoot.Children.Add(r1);
LayoutRoot.Children.Add(r2);
LayoutRoot.Children.Add(l);
LayoutRoot.Children.Add(myPath);