public void Difference_between_square_p_and_square_q_contained_in_p_results_in_p_with_q_added_as_a_hole_contour()
        {
            var corner1    = new Vector2(0.1, 0.2);
            var side1      = 4.5;
            var bigPolygon = (Polygon)Square(corner1, side1, positive: true);

            var corner2      = new Vector2(0.9, 0.8);
            var side2        = 2.3;
            var smallPolygon = (Polygon)Square(corner2, side2, positive: true);

            var result = PolygonUtils.Difference(bigPolygon, smallPolygon);

            Expect(result.Contours.Count, Is.EqualTo(2));

            var contour0 = result.Contours.ElementAt(0);
            var contour1 = result.Contours.ElementAt(1);

            Expect(Math.Sign(contour0.SignedArea()) != Math.Sign(contour1.SignedArea()));

            var outContour = contour0.SignedArea() > 0 ? contour0 : contour1;
            var inContour  = contour0.SignedArea() > 0 ? contour1 : contour0;

            Expect(outContour.Vertices.Count, Is.EqualTo(bigPolygon.CountVertices()));
            Expect(outContour.SignedArea(), Is.EqualTo(bigPolygon.Area()).Within(_tolerance));

            Expect(inContour.Vertices.Count, Is.EqualTo(smallPolygon.CountVertices()));
            Expect(inContour.SignedArea(), Is.EqualTo(-smallPolygon.Area()).Within(_tolerance));
        }
        private void ExpectPolygonsAreEqualWithinTolerance(IPolygon p, IPolygon q, double tolerance)
        {
            var pMinusQ = PolygonUtils.Difference(p, q);
            var qMinusP = PolygonUtils.Difference(q, p);

            Expect(qMinusP.Area(), Is.LessThan(tolerance));
            Expect(pMinusQ.Area(), Is.LessThan(tolerance));
        }
        public void Difference_of_two_empty_polygons_is_empty()
        {
            var p = Polygon.Empty;
            var q = Polygon.Empty;

            var result = PolygonUtils.Difference(p, q);

            Expect(result.IsEmpty);
        }
        public void Intersection_of_3_rectangles_yields_the_correct_square()
        {
            var rectangles = new List <IPolygon>
            {
                new Box2(minX: 0, minY: 0, width: 2, height: 2),
                new Box2(minX: -1, minY: -1, width: 4, height: 2),
                new Box2(minX: -1, minY: -1, width: 2, height: 4)
            };

            var result = PolygonUtils.Intersection(rectangles);

            Expect(result.IsSimple);
            Expect(result.CountVertices(), Is.EqualTo(4));
            Expect(result.Area(), Is.EqualTo(1).Within(_tolerance));

            var resultBox = result.BoundingBox();

            Expect(PolygonUtils.Difference(resultBox, result).Area(), Is.EqualTo(0).Within(_tolerance));
            Expect(resultBox.Width, Is.EqualTo(1).Within(_tolerance));
            Expect(resultBox.Height, Is.EqualTo(1).Within(_tolerance));
            Expect(resultBox.MinCorner.X, Is.EqualTo(0).Within(_tolerance));
            Expect(resultBox.MinCorner.Y, Is.EqualTo(0).Within(_tolerance));
        }
        private IPolygon MakeHoleIn(IPolygon p)
        {
            var hole = new Box2(minX: 1, minY: 1, width: 1, height: 1);

            return(PolygonUtils.Difference(p, hole));
        }