public void CropBy_Plane_with_two_plane_orientations_yields_polygons_lying_on_respective_halfspaces_whose_area_sum_is_the_area_of_the_original_polygon() { 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 polygon2 = PolygonUtils.Union(rectangles); var cs = new RotoTranslation3(new Rotation3(new Quaternion(1.1, -2.2, 3.3, -4.4)), new Vector3(4.1, -2.4, 1.3)); var polygon3 = new Polygon3(cs, polygon2); var point1 = polygon3.PlaneToSpace(new Vector2(0.1, 0.2)); var point2 = polygon3.PlaneToSpace(new Vector2(0.9, 0.7)); var point3 = new Vector3(3.141, 2.718, 0.577); var plane = Plane.Through(point1, point2, point3); var half1 = polygon3.CropBy(plane); var half2 = polygon3.CropBy(plane.Reverse); Expect(half1.IsOnNegativeSide(Plane.ParallelTo(plane, _tolerance))); Expect(half2.IsOnPositiveSide(Plane.ParallelTo(plane, -_tolerance))); Expect(half1.InPlane.Area() + half2.InPlane.Area(), Is.EqualTo(polygon3.InPlane.Area()).Within(_tolerance)); }
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 MinkowskiDifference_of_two_boxes_amounts_to_subtracting_minima_and_maxima() { var box1 = new Box2(new Interval(0.123, 0.456), new Interval(2.718, 3.141)); var box2 = new Box2(new Interval(0.0777, 0.0888), new Interval(-0.1, +0.1)); var expectedAnswer = Box2.Hull(box1.MinCorner - box2.MaxCorner, box1.MaxCorner - box2.MinCorner); var actualAnswer = PolygonUtils.MinkowskiDifference(box1, box2); ExpectPolygonsAreEqualWithinTolerance(actualAnswer, expectedAnswer, _tolerance); }
public void MinkowskiDifference_is_distributive_with_Union() { var box1 = new Box2(new Interval(0.123, 0.456), new Interval(2.718, 3.141)); var box2 = new Box2(new Interval(0.777, 0.888), new Interval(-1, +1)); var box3 = new Box2(new Interval(1.519, 1.784), new Interval(-0.256, +0.324)); var diff1 = PolygonUtils.MinkowskiDifference(box1, PolygonUtils.Union(box2, box3)); var diff2 = PolygonUtils.Union(PolygonUtils.MinkowskiDifference(box1, box2), PolygonUtils.MinkowskiDifference(box1, box3)); ExpectPolygonsAreEqualWithinTolerance(diff1, diff2, _tolerance); }
public void Union_of_3_rectangles_yields_the_correct_octagon() { 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.Union(rectangles); Expect(result.IsSimple); Expect(result.CountVertices(), Is.EqualTo(8)); Expect(result.Area(), Is.EqualTo(13).Within(_tolerance)); var resultBox = result.BoundingBox(); Expect(resultBox.Width, Is.EqualTo(4).Within(_tolerance)); Expect(resultBox.Height, Is.EqualTo(4).Within(_tolerance)); Expect(resultBox.MinCorner.X, Is.EqualTo(-1).Within(_tolerance)); Expect(resultBox.MinCorner.Y, Is.EqualTo(-1).Within(_tolerance)); }
public void CropBy_Line2_with_two_line_orientations_yields_polygons_lying_on_respective_halfplanes_whose_union_is_the_original_polygon() { 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 polygon = PolygonUtils.Union(rectangles); var point1 = new Vector2(0.1, 0.2); var point2 = new Vector2(0.9, 0.7); var line = Line2.Through(point1, point2); var half1 = polygon.CropBy(line); var half2 = polygon.CropBy(line.Reverse); Expect(half1.IsOnNegativeSide(Line2.ParallelTo(line, _tolerance))); Expect(half2.IsOnPositiveSide(Line2.ParallelTo(line, -_tolerance))); ExpectPolygonsAreEqualWithinTolerance(PolygonUtils.Union(half1, half2), polygon, _tolerance); }
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 AddComponentTo(IPolygon p) { var component = new Box2(minX: -2, minY: -2, width: 1, height: 1); return(PolygonUtils.Union(p, component)); }
private IPolygon MakeHoleIn(IPolygon p) { var hole = new Box2(minX: 1, minY: 1, width: 1, height: 1); return(PolygonUtils.Difference(p, hole)); }