I have a simple rectangular PathGeometry
and want to test if the point is inside the PathGeometry
. The obvious way is to call FillContains
but it doesn't work as expected. There is also an overload function which has a tolerance
parameter, although by adjusting the tolerance
to high values FillContains
may return true
but due to the given tolerance calling FillContains
on other geometries may also return true
.
So I wrote this extension method to have a correct FillContains
for this specific rectangular PathGemoetry
:
public static bool Contains(this PathGeometry geo, Point pt)
{
var match = System.Text.RegularExpressions.Regex.Match(geo.Figures.ToString(), @"M(\d*.\d*),(\d*.\d*)L(\d*.\d*),(\d*.\d*) (\d*.\d*),(\d*.\d*) (\d*.\d*),(\d*.\d*)z");
float ulx = float.Parse(match.Groups[1].Value);
float uly = float.Parse(match.Groups[2].Value);
float urx = float.Parse(match.Groups[3].Value);
float ury = float.Parse(match.Groups[4].Value);
float lrx = float.Parse(match.Groups[5].Value);
float lry = float.Parse(match.Groups[6].Value);
float llx = float.Parse(match.Groups[7].Value);
float lly = float.Parse(match.Groups[8].Value);
Rect rect = new Rect(ulx, uly, urx - ulx, lly - uly);
return rect.Contains(pt);
}
And the result for a sample:
// Point: {188.981887817383,507.910125732422}
// Region: M188.759994506836,501.910003662109L216.580001831055,501.910003662109 216.580001831055,511.910003662109 188.759994506836,511.910003662109z
// returns false
var test1 = region.FillContains(pt);
// returns true
var test2 = region.Contains(pt);
Since I have lots of such PathGemoetry
objects then is there any better implementation of mine for faster hit testing or is there anything I missed while using FillContains
resulting in unexpected result?
Edit
Just noticed that my PathGeometry
had a Transform applied to it which result in point not fit inside.
I fixed it by using this to bypass the Transform
in hit-testing:
PathGeometry.Parse(region.Figures.ToString()).FillContains(pt)