public void Polygon_DoesContainLineSegment()
        {
            Point point1 = Point.MakePointWithInches(0, 0);
            Point point2 = Point.MakePointWithInches(2, 0);
            Point point3 = Point.MakePointWithInches(2, 1);
            Point point4 = Point.MakePointWithInches(1, 1);
            Point point5 = Point.MakePointWithInches(1, 2);
            Point point6 = Point.MakePointWithInches(2, 2);
            Point point7 = Point.MakePointWithInches(2, 3);
            Point point8 = Point.MakePointWithInches(0, 3);
            List<Point> vertices = new List<Point>(){point1, point2, point3, point4, point5, point6, point7, point8};
            Polygon cShape = new Polygon(vertices);

            Point basePoint1 = Point.MakePointWithInches(1, 0);
            Point endPoint1 = Point.MakePointWithInches(1, 3);
            LineSegment segmentTouchesInsideEdge = new LineSegment(basePoint1, endPoint1);

            Point basePoint2 = Point.MakePointWithInches(0, 0);
            Point endPoint2 = Point.MakePointWithInches(2, 2);
            LineSegment segmentCutsThroughVertices = new LineSegment(basePoint2, endPoint2);

            Point basePoint3 = Point.MakePointWithInches(1.5, 0);
            Point endPoint3 = Point.MakePointWithInches(.5, 4);
            LineSegment segmentCutsThroughVertexAndEdge = new LineSegment(basePoint3, endPoint3);

            Point basePoint4 = Point.MakePointWithInches(1.5, 0);
            Point endPoint4 = Point.MakePointWithInches(1.5, 3);
            LineSegment segmentCutsThroughEdges = new LineSegment(basePoint4, endPoint4);

            Point basePoint5 = Point.MakePointWithInches(0.5, 0);
            Point endPoint5 = Point.MakePointWithInches(0.5, 3);
            LineSegment segmentIsChord = new LineSegment(basePoint5, endPoint5);


            cShape.Contains(segmentTouchesInsideEdge).Should().BeTrue();
            cShape.Contains(segmentCutsThroughVertices).Should().BeFalse();
            cShape.Contains(segmentCutsThroughVertexAndEdge).Should().BeFalse();
            cShape.Contains(segmentIsChord).Should().BeTrue();
        }
        public void Polygon_Centroid()
        {
            List<LineSegment> bounds = new List<LineSegment>();
            bounds.Add(new LineSegment(Point.Origin, Point.MakePointWithInches(-1, 5, 0)));
            bounds.Add(new LineSegment(Point.Origin, Point.MakePointWithInches(-4, 2, 0)));
            bounds.Add(new LineSegment(Point.MakePointWithInches(-4, 2, 0), Point.MakePointWithInches(-5, 5, 0)));
            bounds.Add(new LineSegment(Point.MakePointWithInches(-1, 5, 0), Point.MakePointWithInches(-5, 5, 0)));
            Polygon testPolygon = new Polygon(bounds);

            Point center = testPolygon.Centroid;
            Point expected = Point.MakePointWithInches(-2.33, 3, 0);

            center.Should().Be(expected);

            //make sure the centroid is in the region
            testPolygon.Contains(center).Should().BeTrue();
            //Note: The Centroid is always contained within the region of a convex polygon.
            //However, for concave polygons this is not the case....

            List<LineSegment> lineSegments = new List<LineSegment>();
            lineSegments.Add(new LineSegment(Point.MakePointWithInches(0, 2, 3), Point.MakePointWithInches(-3, -2, 0)));
            lineSegments.Add(new LineSegment(Point.MakePointWithInches(-3, -2, 0), Point.MakePointWithInches(1, 1, -1)));
            lineSegments.Add(new LineSegment(Point.MakePointWithInches(1, 1, -1), Point.MakePointWithInches(0, 2, 3)));
            Polygon testPolygon2 = new Polygon(lineSegments);

            Point center2 = testPolygon2.Centroid;
            Point expected2 = Point.MakePointWithInches(-0.6666667, 0.33333333, 0.66666667);

            center2.Should().Be(expected2);

            //make sure the centroid is in the region
            testPolygon2.Contains(center2).Should().BeTrue();
        }
        public void Polygon_ContainsPolygon()
        {
            Point pentagonPoint1 = Point.MakePointWithInches(0, 0);
            Point pentagonPoint2 = Point.MakePointWithInches(4, 0);
            Point pentagonPoint3 = Point.MakePointWithInches(2, 2);
            Point pentagonPoint4 = Point.MakePointWithInches(4, 4);
            Point pentagonPoint5 = Point.MakePointWithInches(0, 4);
            Polygon concavePentagon =
                new Polygon(new List<Point>()
                {
                    pentagonPoint1,
                    pentagonPoint2,
                    pentagonPoint3,
                    pentagonPoint4,
                    pentagonPoint5
                });

            Point rectanglePoint1 = Point.MakePointWithInches(1, 1);
            Point rectanglePoint2 = Point.MakePointWithInches(2.5, 1);
            Point rectanglePoint3 = Point.MakePointWithInches(2.5, 3);
            Point rectanglePoint4 = Point.MakePointWithInches(1, 3);
            Polygon rectangle =
                new Polygon(new List<Point>() {rectanglePoint1, rectanglePoint2, rectanglePoint3, rectanglePoint4});

            Point squarePoint1 = Point.MakePointWithInches(1, 1);
            Point squarePoint2 = Point.MakePointWithInches(2, 1);
            Point squarePoint3 = Point.MakePointWithInches(2, 2);
            Point squarePoint4 = Point.MakePointWithInches(1, 2);
            Polygon square = new Polygon(new List<Point>() {squarePoint1, squarePoint2, squarePoint3, squarePoint4});

            concavePentagon.Contains(rectangle).Should().BeFalse();
            rectangle.Contains(concavePentagon).Should().BeFalse();

            concavePentagon.Contains(square).Should().BeTrue();
            square.Contains(concavePentagon).Should().BeFalse();

            rectangle.Contains(square).Should().BeTrue();
            square.Contains(rectangle).Should().BeFalse();
        }
        public void Polygon_ContainsPoint()
        {
            Point pentagonPoint1 = Point.MakePointWithInches(0, 0);
            Point pentagonPoint2 = Point.MakePointWithInches(4, 0);
            Point pentagonPoint3 = Point.MakePointWithInches(2, 2);
            Point pentagonPoint4 = Point.MakePointWithInches(4, 4);
            Point pentagonPoint5 = Point.MakePointWithInches(0, 4);
            Polygon concavePentagon =
                new Polygon(new List<Point>()
                {
                    pentagonPoint1,
                    pentagonPoint2,
                    pentagonPoint3,
                    pentagonPoint4,
                    pentagonPoint5
                });

            Point rectanglePoint1 = Point.MakePointWithInches(1, 1);
            Point rectanglePoint2 = Point.MakePointWithInches(2.5, 1);
            Point rectanglePoint3 = Point.MakePointWithInches(2.5, 3);
            Point rectanglePoint4 = Point.MakePointWithInches(1, 3);
            Polygon rectangle =
                new Polygon(new List<Point>() { rectanglePoint1, rectanglePoint2, rectanglePoint3, rectanglePoint4 });

            Point squarePoint1 = Point.MakePointWithInches(1, 1);
            Point squarePoint2 = Point.MakePointWithInches(2, 1);
            Point squarePoint3 = Point.MakePointWithInches(2, 2);
            Point squarePoint4 = Point.MakePointWithInches(1, 2);
            Polygon square = new Polygon(new List<Point>() { squarePoint1, squarePoint2, squarePoint3, squarePoint4 });

            Point notInPlane = Point.MakePointWithInches(1, 1, 1);
            Point distantPoint = Point.MakePointWithInches(20, 20);
            Point outsidePentagon = Point.MakePointWithInches(3, 2);
            Point onRectangleSegment = Point.MakePointWithInches(1, 1.5);

            concavePentagon.Contains(squarePoint3).Should().BeTrue();
            concavePentagon.Contains(notInPlane).Should().BeFalse();
            concavePentagon.Contains(rectanglePoint1).Should().BeTrue();
            concavePentagon.Contains(distantPoint).Should().BeFalse();
            concavePentagon.Contains(outsidePentagon).Should().BeFalse();

            square.Contains(rectanglePoint1).Should().BeTrue();
            square.Contains(rectanglePoint4).Should().BeFalse();
            square.Contains(pentagonPoint1).Should().BeFalse();
            square.Contains(distantPoint).Should().BeFalse();
            square.Contains(onRectangleSegment).Should().BeTrue();

            rectangle.Contains(rectanglePoint1).Should().BeTrue();
            rectangle.Contains(squarePoint2).Should().BeTrue();
            rectangle.Contains(pentagonPoint1).Should().BeFalse();
            rectangle.Contains(distantPoint).Should().BeFalse();
            rectangle.Contains(onRectangleSegment).Should().BeTrue();

        }
        public void Polygon_Contains_ContainsOnInside_Touches()
        {
            List<LineSegment> bounds = new List<LineSegment>();
            bounds.Add(new LineSegment(Point.Origin, Point.MakePointWithInches(-1, 5, 0)));
            bounds.Add(new LineSegment(Point.Origin, Point.MakePointWithInches(-4, 2, 0)));
            bounds.Add(new LineSegment(Point.MakePointWithInches(-4, 2, 0), Point.MakePointWithInches(-5, 5, 0)));
            bounds.Add(new LineSegment(Point.MakePointWithInches(-1, 5, 0), Point.MakePointWithInches(-5, 5, 0)));
            Polygon testPolygon = new Polygon(bounds);

            Point insidePlane1 = Point.MakePointWithInches(-2, 2, 0);
            Point insidePlane2 = Point.MakePointWithInches(-2, 2, 1);

            Point center1 = testPolygon.CenterPoint;

            //make sure the sides are not included
            Point sideTest = Point.Origin;


            List<LineSegment> lineSegments = new List<LineSegment>();
            lineSegments.Add(new LineSegment(Point.MakePointWithInches(0, 2, 3), Point.MakePointWithInches(-3, -2, 0)));
            lineSegments.Add(new LineSegment(Point.MakePointWithInches(-3, -2, 0), Point.MakePointWithInches(1, 1, -1)));
            lineSegments.Add(new LineSegment(Point.MakePointWithInches(1, 1, -1), Point.MakePointWithInches(0, 2, 3)));
            Polygon testPolygon2 = new Polygon(lineSegments);

            //make sure the PlaneRegion contains the CenterPoint
            Point center2 = testPolygon2.CenterPoint;

            Point notOnPlane = center2.Shift(new Shift(Point.MakePointWithInches(.5, 0, 0)));

            //Points on the plane not boundaries (true for exclusive and inclusive, false for touching)
            testPolygon.ContainsOnInside(insidePlane1).Should().BeTrue();
            testPolygon.Contains(insidePlane1).Should().BeTrue();
            testPolygon.Touches(insidePlane1).Should().BeFalse();

            testPolygon.ContainsOnInside(insidePlane2).Should().BeFalse();
            testPolygon.Contains(insidePlane2).Should().BeFalse();
            testPolygon.Touches(insidePlane2).Should().BeFalse();

            //make sure the PlaneRegion contains the CenterPoint (true for exclusive and inclusive, false for touching)
            testPolygon.ContainsOnInside(center1).Should().BeTrue();
            testPolygon.Contains(center1).Should().BeTrue();
            testPolygon.Touches(center1).Should().BeFalse();

            testPolygon2.ContainsOnInside(center2).Should().BeTrue();
            testPolygon2.Contains(center2).Should().BeTrue();
            testPolygon2.Touches(center2).Should().BeFalse();

            //check the side point (true for inclusive and touches, false for exclusive)
            testPolygon.ContainsOnInside(sideTest).Should().BeFalse();
            testPolygon.Contains(sideTest).Should().BeTrue();
            testPolygon.Touches(sideTest).Should().BeTrue();

            //not on plane (false for all)
            testPolygon2.ContainsOnInside(notOnPlane).Should().BeFalse();
            testPolygon2.Contains(notOnPlane).Should().BeFalse();
            testPolygon2.Touches(notOnPlane).Should().BeFalse();
        }