public bool Intersects(DoubleLineSegment2 other) { double ax = X1, ay = Y1, bx = X2, by = Y2; double cx = other.X1, cy = other.Y1, dx = other.X2, dy = other.Y2; return(Intersects(ax, ay, bx, by, cx, cy, dx, dy)); }
public static int Compare(DoubleVector2 p, DoubleLineSegment2 a, DoubleLineSegment2 b) { // TODO: Why did I comment this //#if DEBUG // if (GeometryOperations.Clockness(p.X, p.Y, a.X1, a.Y1, a.X2, a.Y2) != Clockness.Clockwise) { // throw new InvalidStateException(); // } // if (GeometryOperations.Clockness(p.X, p.Y, b.X1, b.Y1, b.X2, b.Y2) != Clockness.Clockwise) { // throw new InvalidStateException(); // } //#endif var clk = GeometryOperations.Clockness(p.X, p.Y, a.X1, a.Y1, b.X1, b.Y1); if (clk != Clockness.Clockwise) { // b before a; b \' a *origin var res = (int)GeometryOperations.Clockness(b.First, b.Second, a.First); if (res != 0) { return(res); } // just need something to resolve ambiguity. b1 b2 a1 is collinear. // a1 must be within the angle b1 p b2 (see visibility polygon building algorithm) // so a1 is BETWEEN b1 b2. a2 cannot be collinear with b1 b2 (disallow segments intersecting // other than at endpoint), but still, a2 is either 'in front of' or 'behind' b. res = (int)GeometryOperations.Clockness(b.First, b.Second, a.Second); #if DEBUG if (res == 0 && a != b) { throw new BadInputException(); } #endif return(res); } else { // a before b; a \' b *origin var res = -(int)GeometryOperations.Clockness(a.First, a.Second, b.First); if (res != 0) { return(res); } // just need something to resolve ambiguity. a1 a2 b1 is collinear. res = -(int)GeometryOperations.Clockness(a.First, a.Second, b.Second); #if DEBUG if (res == 0 && a != b) { throw new BadInputException(); } #endif return(res); } }
// assumes p is ccw ordered, edge is counted as interior (neither case) public static bool SegmentIntersectsNonDegenerateConvexPolygonInterior(DoubleLineSegment2 s, DoubleVector2[] p) { #if DEBUG if (Clockness(p[0], p[1], p[2]) == Clk.Clockwise) { throw new BadInputException("p not ccw"); } if (p.Length < 3) { throw new BadInputException("len(p) < 3"); } #endif var(x, y) = s; bool xInterior = true, yInterior = true; DoubleVector2 a = p[p.Length - 1], b; int i = 0; for (; i < p.Length && (xInterior || yInterior); i++, a = b) { b = p[i]; var abx = Clockness(a, b, x); var aby = Clockness(a, b, y); if (abx == Clk.Clockwise && aby == Clk.Clockwise) { return(false); } xInterior &= abx != Clk.Clockwise; yInterior &= aby != Clk.Clockwise; if (abx == (Clk)(-(int)aby) || abx == Clk.Neither || aby == Clk.Neither) { // The below is equivalent to: // // (a, b) places x, y onto opposite half-planes. // // Intersect if (x, y) places a, b onto opposite half-planes. // var xya = Clockness(x, y, a); // var xyb = Clockness(x, y, b); // if (xya != xyb || xya == Clk.Neither || xyb == Clk.Neither) return true; if (DoubleLineSegment2.Intersects(a.X, a.Y, b.X, b.Y, x.X, x.Y, y.X, y.Y)) { return(true); } } } for (; i < p.Length; i++, a = b) { b = p[i]; if (DoubleLineSegment2.Intersects(a.X, a.Y, b.X, b.Y, x.X, x.Y, y.X, y.Y)) { return(true); } } return(xInterior && yInterior); }
public static bool SegmentIntersectsConvexPolygonInterior(DoubleLineSegment2 s, DoubleVector2[] p) { if (p.Length == 1) { return(false); } else if (p.Length == 2) { return(s.Intersects(new DoubleLineSegment2(p[0], p[1]))); } else { return(SegmentIntersectsNonDegenerateConvexPolygonInterior(s, p)); } }
public static DoubleVector2 FindNearestPoint(DoubleLineSegment2 segment, DoubleVector2 query) { return(FindNearestPoint(segment.First, segment.Second, query)); }
// NOTE: Assumes lines are valid (two distinct endpoints) NOT line-OVERLAPPING // that is, lines should not have more than 1 point of intersection. // if lines DO have more than 1 point of intersection, this returns no intersection found. public static bool TryFindNonoverlappingLineLineIntersectionT(ref DoubleLineSegment2 a, ref DoubleLineSegment2 b, out double tForA) { return(TryFindNonoverlappingLineLineIntersectionT(a.First, a.Second, b.First, b.Second, out tForA)); }
// Equality by endpoints, not line geometry public bool Equals(DoubleLineSegment2 other) { return(First == other.First && Second == other.Second); }