Reputation: 460
I need to calculate some areas based on Geometry intersection. In my example I have the following Geometries:
The Ellipse is in the middle of the Rectangles and I want two get the following data:
The issue is that the total area of the ellipse, EllipseGeometry.GetArea(), and the "LeftEllipseGeometry".GetArea() + "RightEllipseGeometry".GetArea() are different. The sum of intersections areas have to be the same as the ellipe Area.
I made an example where you can test and see the problem.
MainWindow.xaml.cs
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
//LEFT
rectLeft = new RectangleGeometry();
rectLeft.Rect = new Rect(new Point(75, 100), new Point(700, 600));
Path pathRectLeft = new Path();
pathRectLeft.Stroke = Brushes.Red;
pathRectLeft.Data = rectLeft;
grdMain.Children.Add(pathRectLeft);
//RIGHT
rectRight = new RectangleGeometry();
rectRight.Rect = new Rect(new Point(700, 100), new Point(1300, 600));
Path pathRectRight = new Path();
pathRectRight.Stroke = Brushes.Green;
pathRectRight.Data = rectRight;
grdMain.Children.Add(pathRectRight);
//ELLIPSE
ellipseGeo = new EllipseGeometry();
ellipseGeo.RadiusX = 200;
ellipseGeo.RadiusY = 200;
ellipseGeo.Center = new Point(700, 350);
Path ellipsePath = new Path();
ellipsePath.Stroke = Brushes.Blue;
ellipsePath.Data = ellipseGeo;
grdMain.Children.Add(ellipsePath);
lblEllipseArea.Content = String.Concat("Area Ellipse = ", ellipseGeo.GetArea());
}
private void Button_Click(object sender, RoutedEventArgs e)
{
CombinedGeometry cgLeft = new CombinedGeometry();
cgLeft.Geometry1 = rectLeft;
cgLeft.Geometry2 = ellipseGeo;
cgLeft.GeometryCombineMode = GeometryCombineMode.Intersect;
Path cgLeftPath = new Path();
cgLeftPath.Stroke = Brushes.Yellow;
cgLeftPath.Data = cgLeft;
grdMain.Children.Add(cgLeftPath);
lblEllipseAreaLeft.Content = String.Concat("Area Left Ellipse = ", cgLeft.GetArea());
CombinedGeometry cgRight = new CombinedGeometry();
cgRight.Geometry1 = rectRight;
cgRight.Geometry2 = ellipseGeo;
cgRight.GeometryCombineMode = GeometryCombineMode.Intersect;
Path cgRightPath = new Path();
cgRightPath.Stroke = Brushes.White;
cgRightPath.Data = cgRight;
grdMain.Children.Add(cgRightPath);
lblEllipseAreaRight.Content = String.Concat("Area Right Ellipse = ", cgRight.GetArea());
lblEllipseTotal.Content = String.Concat("Area Ellipse Total = ", cgLeft.GetArea() + cgRight.GetArea());
}
MainWindow.xaml
<Grid>
<StackPanel Orientation="Vertical" Background="Black">
<Grid Background="Black" Height="700" Name="grdMain">
</Grid>
<Grid Background="Black" Height="150">
<StackPanel Orientation="Vertical">
<Button Height="30" Width="70" Click="Button_Click">Click Me!!!</Button>
<StackPanel Orientation="Horizontal">
<Label Foreground="White" Name="lblEllipseArea"></Label>
<Label Foreground="White" Name="lblEllipseArea2" Margin="20 0 0 0"></Label>
<Label Foreground="White" Name="lblEllipseAreaRight" Margin="20 0 0 0"></Label>
<Label Foreground="White" Name="lblEllipseAreaRight2" Margin="20 0 0 0"></Label>
<Label Foreground="White" Name="lblEllipseAreaLeft" Margin="20 0 0 0"></Label>
<Label Foreground="White" Name="lblEllipseAreaLeft2" Margin="20 0 0 0"></Label>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Foreground="White" Name="lblEllipseTotal" Margin="20 0 0 0"></Label>
<Label Foreground="White" Name="lblEllipseTotal2" Margin="20 0 0 0"></Label>
</StackPanel>
</StackPanel>
</Grid>
</StackPanel>
</Grid>
Upvotes: 0
Views: 911
Reputation: 2516
I think you might never get the "exact" areas from the CombinedGeometry. As expected, WPF does not use the "ideal" method to calculate this values. From MSDN: "Some Geometry methods (such as GetArea) produce or use a polygonal approximation of the geometry".
Check MSDN
Upvotes: 1