/// Union /// /// Sets the rectangle to the union of two rectangles r1 and r2. /// If either rect is empty, it is ignored. If both are empty, the rectangle /// is set to r1. /// Either of the input rectangle references may refer to the destination rectangle. /// public void Union(Rect2D r1, Rect2D r2) { if ((r2.Right == r2.Left) || (r2.Bottom == r2.Top)) { Set(r1); } else if ((r1.Right == r1.Left) || (r1.Bottom == r1.Top)) { Set(r2); } else { Left = (r1.Left < r2.Left) ? r1.Left : r2.Left; Top = (r1.Top > r2.Top) ? r1.Top : r2.Top; Right = (r1.Right > r2.Right) ? r1.Right : r2.Right; Bottom = (r1.Bottom < r2.Bottom) ? r1.Bottom : r2.Bottom; } }
public bool Equals(Rect2D r, double epsilon) { if (!MathUtil.AreValuesEqual(MinX, r.MinX, epsilon)) { return(false); } if (!MathUtil.AreValuesEqual(MaxX, r.MaxX)) { return(false); } if (!MathUtil.AreValuesEqual(MinY, r.MinY, epsilon)) { return(false); } if (!MathUtil.AreValuesEqual(MaxY, r.MaxY, epsilon)) { return(false); } return(true); }
public bool Intersects(Rect2D r) { return (Right > r.Left) && (Left < r.Right) && (Bottom < r.Top) && (Top > r.Bottom); }
public bool ContainsInclusive(Rect2D r, double epsilon) { return ((Left - epsilon) <= r.Left) && ((Right + epsilon) >= r.Right) && ((Top - epsilon) <= r.Top) && ((Bottom + epsilon) >= r.Bottom); }
public bool ContainsInclusive(Rect2D r) { return (Left <= r.Left) && (Right >= r.Right) && (Top <= r.Top) && (Bottom >= r.Bottom); }
public bool Contains(Rect2D r) { return (Left < r.Left) && (Right > r.Right) && (Top < r.Top) && (Bottom > r.Bottom); }
public void Set(Rect2D b) { MinX = b.MinX; MaxX = b.MaxX; MinY = b.MinY; MaxY = b.MaxY; }
public bool Equals(Rect2D r) { return(Equals(r, MathUtil.EPSILON)); }
public bool Equals(Rect2D r) { return Equals(r, MathUtil.EPSILON); }
// Given two polygons and their bounding rects, returns true if the two polygons intersect. // This test will NOT determine if one of the two polygons is contained within the other or if the // two polygons are similar - it will return false in all those cases. The only case it will return // true for is if the two polygons actually intersect. public static bool PolygonsIntersect2D( IList<Point2D> poly1, Rect2D boundRect1, IList<Point2D> poly2, Rect2D boundRect2) { // do some quick tests first before doing any real work if (poly1 == null || poly1.Count < 3 || boundRect1 == null || poly2 == null || poly2.Count < 3 || boundRect2 == null) { return false; } if (!boundRect1.Intersects(boundRect2)) { return false; } // We first check whether any edge of one poly intersects any edge of the other poly. If they do, // then the two polys intersect. // Make the epsilon a function of the size of the polys. We could take the heights of the rects // also into consideration here if needed; but, that should not usually be necessary. double epsilon = Math.Max(Math.Min(boundRect1.Width, boundRect2.Width) * 0.001f, MathUtil.EPSILON); int numVerts1 = poly1.Count; int numVerts2 = poly2.Count; for (int i = 0; i < numVerts1; ++i) { int lineEndVert1 = i + 1; if (lineEndVert1 == numVerts1) { lineEndVert1 = 0; } for (int j = 0; j < numVerts2; ++j) { int lineEndVert2 = j + 1; if (lineEndVert2 == numVerts2) { lineEndVert2 = 0; } Point2D tmp = null; if (TriangulationUtil.LinesIntersect2D(poly1[i], poly1[lineEndVert1], poly2[j], poly2[lineEndVert2], ref tmp, epsilon)) { return true; } } } return false; }
public bool ContainsInclusive(Rect2D r, double epsilon) { return(((Left - epsilon) <= r.Left) && ((Right + epsilon) >= r.Right) && ((Top - epsilon) <= r.Top) && ((Bottom + epsilon) >= r.Bottom)); }
public bool ContainsInclusive(Rect2D r) { return((Left <= r.Left) && (Right >= r.Right) && (Top <= r.Top) && (Bottom >= r.Bottom)); }
public bool Contains(Rect2D r) { return((Left < r.Left) && (Right > r.Right) && (Top < r.Top) && (Bottom > r.Bottom)); }
/// Intersection /// /// Sets the rectangle to the intersection of two rectangles. /// Returns true if there is any intersection between the two rectangles. /// If there is no intersection, the rectangle is set to 0, 0, 0, 0. /// Either of the input rectangles may be the same as destination rectangle. /// public bool Intersection(Rect2D r1, Rect2D r2) { if (!TriangulationUtil.RectsIntersect(r1, r2)) { Left = Right = Top = Bottom = 0.0; return false; } Left = (r1.Left > r2.Left) ? r1.Left : r2.Left; Top = (r1.Top < r2.Top ) ? r1.Top : r2.Top; Right = (r1.Right < r2.Right) ? r1.Right : r2.Right; Bottom = (r1.Bottom > r2.Bottom) ? r1.Bottom : r2.Bottom; return true; }
public bool PolygonContainsPolygon(IList<Point2D> poly1, Rect2D boundRect1, IList<Point2D> poly2, Rect2D boundRect2) { return PolygonContainsPolygon(poly1, boundRect1, poly2, boundRect2, true); }
/// <summary> /// Checks to see if poly1 contains poly2. return true if so, false otherwise. /// /// If the polygons intersect, then poly1 cannot contain poly2 (or vice-versa for that matter) /// Since the poly intersection test can be somewhat expensive, we'll only run it if the user /// requests it. If runIntersectionTest is false, then it is assumed that the user has already /// verified that the polygons do not intersect. If the polygons DO intersect and runIntersectionTest /// is false, then the return value is meaningless. Caveat emptor. /// /// As an added bonus, just to cause more user-carnage, if runIntersectionTest is false, then the /// boundRects are not used and can safely be passed in as nulls. However, if runIntersectionTest /// is true and you pass nulls for boundRect1 or boundRect2, you will cause a program crash. /// /// Finally, the polygon points are assumed to be passed in Clockwise winding order. It is possible /// that CounterClockwise ordering would work, but I have not verified the behavior in that case. /// /// </summary> /// <param name="poly1">points of polygon1</param> /// <param name="boundRect1">bounding rect of polygon1. Only used if runIntersectionTest is true</param> /// <param name="poly2">points of polygon2</param> /// <param name="boundRect2">bounding rect of polygon2. Only used if runIntersectionTest is true</param> /// <param name="runIntersectionTest">see summary above</param> /// <returns>true if poly1 fully contains poly2</returns> public static bool PolygonContainsPolygon(IList<Point2D> poly1, Rect2D boundRect1, IList<Point2D> poly2, Rect2D boundRect2, bool runIntersectionTest) { // quick early-out tests if (poly1 == null || poly1.Count < 3 || poly2 == null || poly2.Count < 3) { return false; } if (runIntersectionTest) { // make sure the polygons are not actually the same... if (poly1.Count == poly2.Count) { // Check if the polys are similar to within a tolerance (Doesn't include reflections, // but allows for the points to be numbered differently) if (PolygonUtil.PolygonsAreSame2D(poly1, poly2)) { return false; } } bool bIntersect = PolygonUtil.PolygonsIntersect2D(poly1, boundRect1, poly2, boundRect2); if (bIntersect) { return false; } } // Since we (now) know that the polygons don't intersect and they are not the same, we can just do a // single check to see if ANY point in poly2 is inside poly1. If so, then all points of poly2 // are inside poly1. If not, then ALL points of poly2 are outside poly1. if (PolygonUtil.PointInPolygon2D(poly1, poly2[0])) { return true; } return false; }
public bool Equals(Rect2D r, double epsilon) { if (!MathUtil.AreValuesEqual(MinX, r.MinX, epsilon)) { return false; } if (!MathUtil.AreValuesEqual(MaxX, r.MaxX)) { return false; } if (!MathUtil.AreValuesEqual(MinY, r.MinY, epsilon)) { return false; } if (!MathUtil.AreValuesEqual(MaxY, r.MaxY, epsilon)) { return false; } return true; }
public static bool RectsIntersect(Rect2D r1, Rect2D r2) { return (r1.Right > r2.Left) && (r1.Left < r2.Right) && (r1.Bottom > r2.Top) && (r1.Top < r2.Bottom); }