shared area of two shapes in wpf - wpf

I'm making an app that is a venn diagram and I don't know how to do the first step. There are to ellipses and I want to color the shared area of two ellipses.
The green area is the shared area I meant.

You can use intersect mode on a combinedgeometry to find the parts overlap:
<Grid>
<Grid.Background>
<VisualBrush Stretch="None">
<VisualBrush.Visual>
<Canvas>
<Path Fill="Yellow">
<Path.Data>
<EllipseGeometry Center="150,50" RadiusX="75" RadiusY="75" />
</Path.Data>
</Path>
<Path Fill="Yellow">
<Path.Data>
<EllipseGeometry Center="50,50" RadiusX="75" RadiusY="75" />
</Path.Data>
</Path>
<Path Fill="Green">
<Path.Data>
<CombinedGeometry GeometryCombineMode="Intersect">
<CombinedGeometry.Geometry1>
<EllipseGeometry Center="150,50" RadiusX="75" RadiusY="75"/>
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<EllipseGeometry Center="50,50" RadiusX="75" RadiusY="75"/>
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
</Grid.Background>
Position textblocks in the grid on top of the background shapes using rows and columns.
Or just put everything in a canvas rather than using a visualbrush.
Use Canvas.Left and Canvas.Top to position some textblocks on top of the ellipses.

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.

WPF Callout Anchor start position

I have implement Callout control of Blend. Problem which I am facing is anchor point of the Callout starts with some margin from the top, While I want to have anchor from the top left of the callout.
Any help will be appreciated.
What I have now:
What I would like to have:
You seem to be mistaken about using this control. From MSDN, the Callout.AnchorPoint property Gets or sets the position of the callout relative to the top and left corner. It is used for positioning the control and does not alter the shape of the Callout.
UPDATE >>>
Dude!!! That's a really simple shape... just draw your own one with a Path... then you can make it any shape you want:
<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
<Path.Data>
<CombinedGeometry GeometryCombineMode="Union">
<CombinedGeometry.Geometry1>
<RectangleGeometry RadiusX="20" RadiusY="20" Rect="0,0,300,200">
<RectangleGeometry.Transform>
<TranslateTransform X="30" />
</RectangleGeometry.Transform>
</RectangleGeometry>
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<PathGeometry>
<PathFigure StartPoint="0,30">
<LineSegment Point="50,10" />
<LineSegment Point="50,50" />
</PathFigure>
</PathGeometry>
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
<Path.Effect>
<DropShadowEffect Color="Black" Opacity="0.4" Direction="-135"
ShadowDepth="10" />
</Path.Effect>
</Path>

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>

Explicit geometry bounds

I encountered following problem during creation of radioactive geometry:
Orange dot represents RadialGradientBrush center point (0,0). It should be in the center of black circle, not on the bottom. This cause another problem: spinning animation.
Is there a way to fix this at the geometry level ? I could fix it by setting brush's center point explicitly, but that is inconvenient and brittle.
<GeometryDrawing>
<GeometryDrawing.Geometry>
<GeometryGroup>
<PathGeometry Figures="
M-10,0 Q0,5 10,0
Q20,25 25,50
Q0,60 -25,50
Q-20,25 -10,0 Z">
<PathGeometry.Transform>
<TranslateTransform Y="15" />
</PathGeometry.Transform>
</PathGeometry>
<PathGeometry Figures="
M-10,0 Q0,5 10,0
Q20,25 25,50
Q0,60 -25,50
Q-20,25 -10,0 Z" >
<PathGeometry.Transform>
<TransformGroup>
<TranslateTransform Y="15" />
<RotateTransform Angle="120" />
</TransformGroup>
</PathGeometry.Transform>
</PathGeometry>
<PathGeometry Figures="
M-10,0 Q0,5 10,0
Q20,25 25,50
Q0,60 -25,50
Q-20,25 -10,0 Z" >
<PathGeometry.Transform>
<TransformGroup>
<TranslateTransform Y="15" />
<RotateTransform Angle="240" />
</TransformGroup>
</PathGeometry.Transform>
</PathGeometry>
<EllipseGeometry RadiusX="10" RadiusY="10" />
</GeometryGroup>
</GeometryDrawing.Geometry>
<GeometryDrawing.Brush>
<RadialGradientBrush ColorInterpolationMode="ScRgbLinearInterpolation">
<GradientStop Offset="0" Color="Orange" />
<GradientStop Offset="0.03" Color="Black" />
</RadialGradientBrush>
</GeometryDrawing.Brush>
<GeometryDrawing.Pen>
<Pen Thickness="0">
<Pen.Brush>
<SolidColorBrush Color="Black" />
</Pen.Brush>
</Pen>
</GeometryDrawing.Pen>
</GeometryDrawing>
This is caused by the fact that the top of the box cuts off the top of the big circle. It is cut off because the top two petals are rotated.
You could fix this by adding the outer circle (transparent) to the geometry or perhaps by adding a margin to the top.
this will move down the black parts of the drawing, centering the orange dot and fixing the rotation.
Does this make sense? It is hard to explain, when needed I could create a sketch.

How to turn off anti-aliasing for DrawingBrush?

I want to draw a triangle as a border background. One way of doing this is by using a DrawingBrush, but at smaller sizes anti-aliasing is distorting the triangle and making it blurry. How can I disable anti-aliasing?
<Border>
<Border.Background>
<DrawingBrush>
<DrawingBrush.Drawing>
<GeometryDrawing Brush="Red">
<GeometryDrawing.Geometry>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure IsClosed="True" StartPoint="0,3" IsFilled="True">
<PathFigure.Segments>
<LineSegment Point="3,0" />
<LineSegment Point="6,3" />
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Border.Background>
</Border>
I've tried setting RenderOptions.EdgeMode="Aliased" and SnapsToDevicePixels="true" on all possible elements, but that hasn't worked...
Edit:
This is what the drawn triangle looks like at Width=17; Height=12 (zoomed to 800%):
As you can see the edges are anti-aliased. All the usual options for disabling anti-aliasing don't seem to be working...
I also became very frustrated with this. After some research, I found the answer: Using a Visual Brush with the Image element in the visual set to SnapToDevicePixels = true and Aliased Edge Mode. See the example below:
<Canvas VerticalAlignment="Top" Height="12" Margin="0,24,0,0">
<Canvas.Background>
<VisualBrush TileMode="Tile" Stretch="None" Viewport="-5,0,10,10" ViewportUnits="Absolute">
<VisualBrush.Visual>
<Image Stretch="None" RenderOptions.EdgeMode="Aliased" SnapsToDevicePixels="True">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<GeometryDrawing>
<GeometryDrawing.Pen>
<Pen Brush="#8F8E8F" Thickness="1" />
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<LineGeometry StartPoint="0,0" EndPoint="0,10"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</VisualBrush.Visual>
</VisualBrush>
</Canvas.Background>
</Canvas>
Considering there haven't been any more replies, then it seems that the answer is - it's impossible.
I think you should be able to do it with SnapToDevicePixels (although sometimes it takes a little trial and error). You should set it on the owning object (so whatever the border is being put in). Have you read this article?
http://msdn.microsoft.com/en-us/library/aa970908.aspx

Resources