How to draw a circle with x mark? - wpf

I'm trying to draw a circle with perfect X mark.
I managed to draw a circle with half of the X mark. I'm not sure how to draw the second half.
Thank you
<Path Stroke="Black"
StrokeThickness="4" Fill="Red" VerticalAlignment="Center" HorizontalAlignment="Center">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure StartPoint="0,0">
<PathFigure.Segments>
<LineSegment Point="100,100" />
<ArcSegment Size="50,50"
RotationAngle="45"
IsLargeArc="True"
SweepDirection="Clockwise"
Point="0,0" />
<ArcSegment Size="50,50"
RotationAngle="45"
IsLargeArc="True"
SweepDirection="Clockwise"
Point="100,100" />
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>

You can "simplify" this, or at least make it take up less space in the XAML editor, by using Path Markup Syntax. The portion of Data before the blank line reproduces what you've already got: M for "move", L for "line to", A for "arc". The "Move" and "Line To" commands after the blank line add the second line.
<Path
Stroke="Black"
StrokeThickness="4"
Fill="Red"
Data="
M 0,0
L 100,100
A 50,50 45 1 1 0,0
A 50,50 45 1 1 100,100
M 100,0
L 0,100"
/>
You don't need to format it with newlines like that; I just inserted the newlines to clarify how it maps onto your version. Fortunately, you added the attributes to your ArcSegment elements in the same order as the corresponding arguments to A in the markup syntax.
This is how it's usually done, though it's arguably less readable:
Data="M 0,0 L 100,100 A 50,50 45 1 1 0,0 A 50,50 45 1 1 100,100 M 100,0 L 0,100"
Alternatively, to finish it the same way you started, just add the second line as another PathFigure:
<Path
Stroke="Black"
StrokeThickness="4"
Fill="Red"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure StartPoint="0,0">
<PathFigure.Segments>
<LineSegment Point="100,100" />
<ArcSegment
Size="50,50"
RotationAngle="45"
IsLargeArc="True"
SweepDirection="Clockwise"
Point="0,0"
/>
<ArcSegment
Size="50,50"
RotationAngle="45"
IsLargeArc="True"
SweepDirection="Clockwise"
Point="100,100"
/>
</PathFigure.Segments>
</PathFigure>
<!-- Second line -->
<PathFigure StartPoint="100,0">
<PathFigure.Segments>
<LineSegment Point="0,100" />
</PathFigure.Segments>
</PathFigure>
<!-- /Second line -->
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>

use this...https://materialdesignicons.com/
<Viewbox Width="48" Height="48">
<Canvas Width="24" Height="24">
<Path Data="M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2C6.47,2 2,6.47 2,12C2,17.53 6.47,22 12,22C17.53,22 22,17.53 22,12C22,6.47 17.53,2 12,2M14.59,8L12,10.59L9.41,8L8,9.41L10.59,12L8,14.59L9.41,16L12,13.41L14.59,16L16,14.59L13.41,12L16,9.41L14.59,8Z" Fill="Black" />
</Canvas>

Related

Ellipse with CombinedGeometry

I have this ellipse:
<Ellipse Name="backgroundEllipse1" Fill="Pink">
<Ellipse.Clip>
<CombinedGeometry GeometryCombineMode="Exclude">
<CombinedGeometry.Geometry1>
<EllipseGeometry x:Name="backgroundEllipseMask1" Center="150,150" RadiusX="300" RadiusY="300"></EllipseGeometry>
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<EllipseGeometry x:Name="backgroundEllipseMask2" Center="150,150" RadiusX="130" RadiusY="130"></EllipseGeometry>
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Ellipse.Clip>
</Ellipse>
How can I make something like this?
I'm trying to combine the center and Radius values but something escapes me.
You need an ArcSegment
<Canvas>
<Path Stroke="Pink" StrokeThickness="10" >
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="400,400">
<ArcSegment IsLargeArc="True"
Size="100, 100"
Point="480, 410"
SweepDirection="Counterclockwise" />
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
</Canvas>
Note that the arc starts form (400,400) and ends in (480,410). It moves Counterclockwise and is a large arc. Size="100, 100" determines the size of the Ellipse (or Circle if they are equal) This post can help you.

Drawing an arrow end on a Quadratic Bezier Segment using xaml

What's the easiest way to draw an arrow at the end of a QuadraticBezierSegment? The tricky part is to get the correct rotation to mach the incoming line segment.
Any ideas on how to go about this? Should I extend PathSegment?
I've got this for drawing a simple bezier line.
<Path Stroke="Black" StrokeThickness="1">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure StartPoint="100,430">
<PathFigure.Segments>
<PathSegmentCollection>
<QuadraticBezierSegment Point1="150,250" Point2="250,300" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
You could define the geometry for the arrow head....but it would take trial and error to correctly orientate it on the end of the bezier curve.
Instead you could use this control and define the endcap you wanted using geometry and it properly places it on the end of the "line".
http://blogs.msdn.com/b/mrochon/archive/2011/01/10/custom-line-caps-in-wpf.aspx
<loc:CappedLine Stroke="Red" StrokeThickness="1" Canvas.Left="40" Canvas.Top="200" RenderTransformOrigin="0.5,0.5" Height="107" Width="195">
<loc:CappedLine.EndCap>
<GeometryGroup>
<LineGeometry StartPoint="0,0" EndPoint="10,10"/>
<LineGeometry StartPoint="0,0" EndPoint="10,-10"/>
</GeometryGroup>
</loc:CappedLine.EndCap>
<loc:CappedLine.LinePath>
<PathGeometry Figures="M0,0 C1,1 10.5,75.5 48.5,66.5 86.5,57.5 5,3.5000146 105.5,16.500091 157.5,29.500166 164.5,87.500505 164.5,87.500505" />
</loc:CappedLine.LinePath>
</loc:CappedLine>
<loc:CappedLine Stroke="Red" StrokeThickness="1" Canvas.Left="180" Canvas.Top="200" RenderTransformOrigin="0.5,0.5" Height="107" Width="195">
<loc:CappedLine.EndCap>
<GeometryGroup>
<LineGeometry StartPoint="0,0" EndPoint="10,10"/>
<LineGeometry StartPoint="0,0" EndPoint="10,-10"/>
</GeometryGroup>
</loc:CappedLine.EndCap>
<loc:CappedLine.LinePath>
<PathGeometry Figures="M0,0 C1,1 10.5,75.5 48.5,66.5 86.5,57.5 5,3.5000146 105.5,16.500091" />
</loc:CappedLine.LinePath>
</loc:CappedLine>

How to make WPF Shapes Completely Filled

I have a path like this,
<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="6.0,12.5" >
<LineSegment Point="50.0,6.0"></LineSegment>
<LineSegment Point="94.0,12.5"></LineSegment>
<LineSegment Point="60.0,19.0"></LineSegment>
<LineSegment Point="20.0,19.0"></LineSegment>
<LineSegment Point="6.0,12.5"></LineSegment>
</PathFigure>
<PathFigure StartPoint="7.97852754592896,12.2077178955078">
<ArcSegment IsLargeArc="True" Point="4.02147245407104,12.7922821044922" RotationAngle="171.59663391113281" Size="2,4" SweepDirection="Counterclockwise"></ArcSegment>
<ArcSegment IsLargeArc="True" Point="7.97852754592896,12.2077178955078" RotationAngle="171.59663391113281" Size="2,4" SweepDirection="Counterclockwise"></ArcSegment>
</PathFigure>
<PathFigure StartPoint="51.9785270690918,6.29228210449219">
<ArcSegment IsLargeArc="True" Point="48.0214729309082,5.70771789550781" RotationAngle="188.40336608886719" Size="2,4" SweepDirection="Counterclockwise"></ArcSegment>
<ArcSegment IsLargeArc="True" Point="51.9785270690918,6.29228210449219" RotationAngle="188.40336608886719" Size="2,4" SweepDirection="Counterclockwise"></ArcSegment>
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
It represents a polygon with some circles at a couple of the corners.
One of the circles is not filled in correctly. It happens to be part of the circle that covers the polygon.
It reminds me of graphics that use XOR. Put two over the top of each other and they cancel out.
If I remove the polygon (the linesegments) then it works fine.
In looking at your Path and playing around with the PathGeometry.FillRule Property I am getting the same results for both of the options.
This is using the Nonzero FilRule with a single Path.
The only way that I was able to get the results I beleive you are looking for was to use the Nonzero FillRule and create a seperate path for the problem PathFigure's.
This is using the Nonzero FillRule with a seperate Path for the problem PathFigures.
<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
<Path.Data>
<PathGeometry FillRule="Nonzero">
<PathFigure StartPoint="6.0,12.5" >
<LineSegment Point="50.0,6.0"></LineSegment>
<LineSegment Point="94.0,12.5"></LineSegment>
<LineSegment Point="60.0,19.0"></LineSegment>
<LineSegment Point="20.0,19.0"></LineSegment>
<LineSegment Point="6.0,12.5"></LineSegment>
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
<Path.Data >
<PathGeometry FillRule="Nonzero">
<PathFigure StartPoint="51.9785270690918,6.29228210449219">
<ArcSegment IsLargeArc="True" Point="48.0214729309082,5.70771789550781" RotationAngle="188.40336608886719" Size="2,4" SweepDirection="Counterclockwise"></ArcSegment>
<ArcSegment IsLargeArc="True" Point="51.9785270690918,6.29228210449219" RotationAngle="188.40336608886719" Size="2,4" SweepDirection="Counterclockwise" ></ArcSegment>
</PathFigure>
<PathFigure StartPoint="7.97852754592896,12.2077178955078" >
<ArcSegment IsLargeArc="True" Point="4.02147245407104,12.7922821044922" RotationAngle="171.59663391113281" Size="2,4" SweepDirection="Counterclockwise"></ArcSegment>
<ArcSegment IsLargeArc="True" Point="7.97852754592896,12.2077178955078" RotationAngle="171.59663391113281" Size="2,4" SweepDirection="Counterclockwise"></ArcSegment>
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
On your PathGeometry element try setting
FillRule="NonZero"
The default of EvenOdd gives the XOR behavior you're describing.

Equivalent of IsFilled="false" for PathFigure in Path Mini-language (Silverlight/WPF)

I'm trying to find the equivalent of IsFilled="False" that is used in a PathGeometry, but for Path Mini.
You can see that the two paths below are identical, except for the one with geometries has IsFilled="False" in the second <PathGeometry>.<PathGeometry.Figures>.<PathFigure>. This is the desired behavior, but I'd like to have it for a Path Mini (i.e. in the first <Path>). I've looked through the documentation and can't seem to locate anything on it as it appears that Path Mini is not a collection of figures.
As I understand it, all shapes/geometries will get converted to path mini at run-time, so is there some way to reflect the compiled XAML to see how the interpreter renders the one with PathGeometry to Path Mini?
<Canvas Background="#FDB" Width="800" Height="600">
<!-- this is the LEFT-HAND Path in the picture above -->
<Path Canvas.Left="100" Canvas.Top="100"
Stroke="#385D8A" StrokeThickness="2" StrokeLineJoin="Round" Fill="#4F81BD"
Data="M0,0L102,0L102,102L0,102Z M46.15,49.01L-73.36,130.99L-96.42,-96.12L109.35,355.18">
</Path>
<!-- this is the RIGHT-HAND Path in the picture above -->
<Path Canvas.Left="300" Canvas.Top="100" Stroke="#385D8A" StrokeThickness="2" StrokeLineJoin="Round" Fill="#4F81BD">
<Path.Data>
<GeometryGroup>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure StartPoint="0,0" IsClosed="True">
<PathFigure.Segments>
<LineSegment Point="102,0" />
<LineSegment Point="102,102" />
<LineSegment Point="0,102" />
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure IsFilled="False" StartPoint="46.15,49.01">
<PathFigure.Segments>
<LineSegment Point="-73.36,130.99" />
<LineSegment Point="-96.42,-96.12" />
<LineSegment Point="109.35,355.18" />
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</GeometryGroup>
</Path.Data>
</Path>
</Canvas>
The path mini-lanuage only supports outlines so strokes must be converted to fills. This is straightforward to do yourself if you want one-pixel wide lines and you aren't too fussy about mitering or endcaps. Just use skinny rectangles. A true mathematical "grow" of an infinitely narrow stroke using the minimum number of points and handling crossings is quite a bit harder. However you might be able to use the WPF rendering engine to do that for you since obviously it can already do it.

Rotation and Direction of ArcSegment

Is there a way to get an ArcSegment to draw in a particular direction? As far as I can tell, it is always drawing top to bottom to top. For example, I have an ArcSegment which starts at 180 degrees (270 degrees is north) and draws an almost ellipse to 180 degrees. Right now, the drawing goes clockwise from....well, sorry, let me show you.
The left-hand one is the values I receive from a conversion set of values, but I need it to act like the right-hand one.
<Canvas Background="#FDB" Width="720" Height="540">
<Path Canvas.Left="100" Canvas.Top="100" Stroke="#385D8A" StrokeThickness="2" StrokeLineJoin="Round" Fill="#4F81BD">
<!-- this is the LEFT shape that I need drawn like the other one -->
<Path.Data>
<GeometryGroup>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure StartPoint="0,51" IsClosed="True">
<PathFigure.Segments>
<LineSegment Point="51,51" />
</PathFigure.Segments>
</PathFigure>
<PathFigure StartPoint="25.5,0">
<PathFigure.Segments>
<LineSegment Point="25.5,102" />
</PathFigure.Segments>
</PathFigure>
<PathFigure StartPoint="25.5,51" IsClosed="True" >
<PathFigure.Segments>
<ArcSegment Size="25.5,25.5" IsLargeArc="True" SweepDirection="Clockwise" Point="25.49,51" />
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</GeometryGroup>
</Path.Data>
</Path>
<Path Canvas.Left="200" Canvas.Top="100" Stroke="#385D8A" StrokeThickness="2" StrokeLineJoin="Round" Fill="#4F81BD">
<!-- this is the RIGHT shape, the way it should behave, but notice the different StartPoint and Point -->
<Path.Data>
<GeometryGroup>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure StartPoint="0,51" IsClosed="True">
<PathFigure.Segments>
<LineSegment Point="51,51" />
</PathFigure.Segments>
</PathFigure>
<PathFigure StartPoint="25.5,0">
<PathFigure.Segments>
<LineSegment Point="25.5,102" />
</PathFigure.Segments>
</PathFigure>
<PathFigure StartPoint="51,25.5" IsClosed="True" >
<PathFigure.Segments>
<ArcSegment Size="25.5,25.5" IsLargeArc="True" SweepDirection="Clockwise" Point="50.99,25.5" />
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</GeometryGroup>
</Path.Data>
</Path>
</Canvas>
I've tried toying around with RotationAngle, but that doesn't seem to have any effect as it works only with the X-axis, not Y-axis.
The first Path's values come from a conversion routine, so it's not that I can easily modify them.
I think I've figured it out - just make the Y-axis shorter instead of the X-axis. So:
<PathFigure StartPoint="51,25.5" IsClosed="True" >
<PathFigure.Segments>
<ArcSegment Point="50.99,25.5" Size="25.5,25.5" IsLargeArc="True" SweepDirection="Clockwise" />
</PathFigure.Segments>
</PathFigure>
should be:
<PathFigure StartPoint="51,25.5" IsClosed="True" >
<PathFigure.Segments>
<ArcSegment Point="51,24.99" Size="25.5,25.5" IsLargeArc="True" SweepDirection="Clockwise" />
</PathFigure.Segments>
</PathFigure>
As simple as that.

Resources