Intro
I noticed an issue while implementing clipping (see this).
It looks like UIElement.Clip still render invisible parts
Rendering relatively small geometry (lines to only fill 1920x1200 area ~ 2000 vertical lines) take a lot of time. When using Clip
and moving that geometry offscreen (so that clipping should remove significant part of it) it is still take same time (around 1 sec).
Ok, I found what using Geometry.Combine
will do a clip (render time is reduced proportionally to removed after clipping geometry). Perfect!
Problem
Geometry.Combine
doesn't work with non-closed geometry properly. It produce closed geometry. And it looks ugly, connecting first and last point:
Question
How can I perform clipping (reducing amount of geometry to be rendered) for non-closed figures?
Edit
Here is geometry before (small peace of shown on picture)
{M0;50L0;50L1;53,1395259764657L2;56,2666616782152L3;59,3690657292862L4;62,4344943582427L5;65,4508497187474L6;68,4062276342339L7;71,2889645782536L8; ...
and after
{F1M54,9999923706055;34,5491371154785L53,9999885559082;37,5655174255371 53,0000114440918;40,6309471130371 52,0000076293945;43,7333335876465 ...
Notice change at beginning, was M 0;50 L ...
, become F 1 M 55;34 L ...
F1
means NonZero
filling
Rule that determines whether a point is in the fill region of the path by drawing a ray from that point to infinity in any direction and then examining the places where a segment of the shape crosses the ray. Starting with a count of zero, add one each time a segment crosses the ray from left to right and subtract one each time a path segment crosses the ray from right to left. After counting the crossings, if the result is zero then the point is outside the path. Otherwise, it is inside.
And I have absolutely no clue what that means. But maybe it is important?
Edit
I should have been looking at the end of strings. There is z
at the end of Path.Data
, which means figure is closed.
Strangely enough, trying to remove z
(by using Geometry.ToString()
/Geometry.Parse()
combo) doesn't works. After some investigation I found what Combine
produces physically enclosing figures (commands L x;y
, where x;y
is the leftmost point). And the worst thing is what it's not always the last point, so simply removing last L x;y
before parsing doesn't works either. =(
Edit
Sample to demonstrate problem:
Xaml:
<Path x:Name="path" Stroke="Red"/>
Code:
var geometry1 = new RectangleGeometry(new Rect(100, 100, 100, 100));
var geometry2 = new PathGeometry(new[] { new PathFigure(new Point(0,0), new[] {
new LineSegment(new Point(300, 300), true),
new LineSegment(new Point(300, 0), true),
}, false) });
//path.Data = geometry1;
//path.Data = geometry2;
//path.Data = Geometry.Combine(geometry1, geometry2, GeometryCombineMode.Intersect, null);
Pictures of geometry1
and geometry2
:
Resulting Combine
:
As you can see 2 lines become 3 after clipping, debugging proves it:
{F1M100;100L200;100 200;200 100;100z}
Notice, it's not only z
, but also 100;100
point at the end, connecting starting point.