You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
6.7 KiB
C#

using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Clipper2Lib.UnitTests
{
[TestClass]
public class TestPolytree
{
private void PolyPathContainsPoint(PolyPath64 pp, Point64 pt, ref int counter)
{
if (Clipper.PointInPolygon(pt, pp.Polygon!) != PointInPolygonResult.IsOutside)
{
if (pp.IsHole) --counter; else ++counter;
}
for (int i = 0; i < pp.Count; i++)
{
PolyPath64 child = (PolyPath64) pp[i];
PolyPathContainsPoint(child, pt, ref counter);
}
}
private bool PolytreeContainsPoint(PolyTree64 pp, Point64 pt)
{
int counter = 0;
for (int i = 0; i < pp.Count; i++)
{
PolyPath64 child = (PolyPath64) pp[i];
PolyPathContainsPoint(child, pt, ref counter);
}
Assert.IsTrue(counter >= 0, "Polytree has too many holes");
return counter != 0;
}
private bool PolyPathFullyContainsChildren(PolyPath64 pp)
{
foreach (PolyPath64 child in pp.Cast<PolyPath64>())
{
foreach (Point64 pt in child.Polygon!)
if (Clipper.PointInPolygon(pt, pp.Polygon!) == PointInPolygonResult.IsOutside)
return false;
if (child.Count > 0 && !PolyPathFullyContainsChildren(child))
return false;
}
return true;
}
private bool CheckPolytreeFullyContainsChildren(PolyTree64 polytree)
{
for (int i = 0; i < polytree.Count; i++)
{
PolyPath64 child = (PolyPath64) polytree[i];
if (child.Count > 0 && !PolyPathFullyContainsChildren(child))
return false;
}
return true;
}
[TestMethod]
public void TestPolytree2()
{
Paths64 subject = new(), subjectOpen = new(), clip = new();
Assert.IsTrue(ClipperFileIO.LoadTestNum("..\\..\\..\\..\\..\\..\\Tests\\PolytreeHoleOwner2.txt",
1, subject, subjectOpen, clip, out ClipType cliptype, out FillRule fillrule,
out _, out _, out _),
"Unable to read PolytreeHoleOwner2.txt");
PolyTree64 solutionTree = new();
Paths64 solution_open = new();
Clipper64 clipper = new();
Path64 pointsOfInterestOutside = new()
{
new Point64(21887, 10420),
new Point64(21726, 10825),
new Point64(21662, 10845),
new Point64(21617, 10890)
};
foreach (Point64 pt in pointsOfInterestOutside)
{
foreach (Path64 path in subject)
{
Assert.IsTrue(Clipper.PointInPolygon(pt, path) == PointInPolygonResult.IsOutside,
"outside point of interest found inside subject");
}
}
Path64 pointsOfInterestInside = new()
{
new Point64(21887, 10430),
new Point64(21843, 10520),
new Point64(21810, 10686),
new Point64(21900, 10461)
};
foreach (Point64 pt in pointsOfInterestInside)
{
int poi_inside_counter = 0;
foreach (Path64 path in subject)
{
if (Clipper.PointInPolygon(pt, path) == PointInPolygonResult.IsInside)
poi_inside_counter++;
}
Assert.IsTrue(poi_inside_counter == 1,
string.Format("poi_inside_counter - expected 1 but got {0}", poi_inside_counter));
}
clipper.AddSubject(subject);
clipper.AddOpenSubject(subjectOpen);
clipper.AddClip(clip);
clipper.Execute(cliptype, fillrule, solutionTree, solution_open);
Paths64 solutionPaths = Clipper.PolyTreeToPaths64(solutionTree);
double a1 = Clipper.Area(solutionPaths), a2 = solutionTree.Area();
Assert.IsTrue(a1 > 330000,
string.Format("solution has wrong area - value expected: 331,052; value returned; {0} ", a1));
Assert.IsTrue(Math.Abs(a1 - a2) < 0.0001,
string.Format("solution tree has wrong area - value expected: {0}; value returned; {1} ", a1, a2));
Assert.IsTrue(CheckPolytreeFullyContainsChildren(solutionTree),
"The polytree doesn't properly contain its children");
foreach (Point64 pt in pointsOfInterestOutside)
Assert.IsFalse(PolytreeContainsPoint(solutionTree, pt),
"The polytree indicates it contains a point that it should not contain");
foreach (Point64 pt in pointsOfInterestInside)
Assert.IsTrue(PolytreeContainsPoint(solutionTree, pt),
"The polytree indicates it does not contain a point that it should contain");
}
[TestMethod]
public void TestPolytree3()
{
Paths64 subject = new();
subject.Add(Clipper.MakePath(new int[] {1588700, -8717600,
1616200, -8474800, 1588700, -8474800 }));
subject.Add(Clipper.MakePath(new int[] { 13583800,-15601600,
13582800,-15508500, 13555300,-15508500, 13555500,-15182200,
13010900,-15185400 }));
subject.Add(Clipper.MakePath(new int[] { 956700, -3092300, 1152600,
3147400, 25600, 3151700 }));
subject.Add(Clipper.MakePath(new int[] {
22575900,-16604000, 31286800,-12171900,
31110200,4882800, 30996200,4826300, 30414400,5447400, 30260000,5391500,
29662200,5805400, 28844500,5337900, 28435000,5789300, 27721400,5026400,
22876300,5034300, 21977700,4414900, 21148000,4654700, 20917600,4653400,
19334300,12411000, -2591700,12177200, 53200,3151100, -2564300,12149800,
7819400,4692400, 10116000,5228600, 6975500,3120100, 7379700,3124700,
11037900,596200, 12257000,2587800, 12257000,596200, 15227300,2352700,
18444400,1112100, 19961100,5549400, 20173200,5078600, 20330000,5079300,
20970200,4544300, 20989600,4563700, 19465500,1112100, 21611600,4182100,
22925100,1112200, 22952700,1637200, 23059000,1112200, 24908100,4181200,
27070100,3800600, 27238000,3800700, 28582200,520300, 29367800,1050100,
29291400,179400, 29133700,360700, 29056700,312600, 29121900,332500,
29269900,162300, 28941400,213100, 27491300,-3041500, 27588700,-2997800,
22104900,-16142800, 13010900,-15603000, 13555500,-15182200,
13555300,-15508500, 13582800,-15508500, 13583100,-15154700,
1588700,-8822800, 1588700,-8379900, 1588700,-8474800, 1616200,-8474800,
1003900,-630100, 1253300,-12284500, 12983400,-16239900}));
subject.Add(Clipper.MakePath(new int[] { 198200, 12149800, 1010600, 12149800, 1011500, 11859600 }));
subject.Add(Clipper.MakePath(new int[] { 21996700, -7432000, 22096700, -7432000, 22096700, -7332000 }));
PolyTree64 solutionTree = new();
Clipper64 clipper = new();
clipper.AddSubject(subject);
clipper.Execute(ClipType.Union, FillRule.NonZero, solutionTree);
Assert.IsTrue(solutionTree.Count == 1 && solutionTree[0].Count == 2
&& solutionTree[0][1].Count == 1, "Incorrect PolyTree nesting.");
} // end TESTMETHOD TestPolytree3
} // end TestClass
}