Example #1
0
        public static IntersectionType IntSegmentToIntSegmentE(IntSegment2 segment0, IntSegment2 segment1,
                                                               bool testBoundingBox = false)
        {
            IntSegment2 intersection;

            return(IntSegmentToIntSegmentE(segment0.a, segment0.b, segment1.a, segment1.b, out intersection,
                                           testBoundingBox));
        }
Example #2
0
 public int CompareByLength(IntSegment2 segment)
 {
     if (length > segment.length)
     {
         return(1);
     }
     if (length == segment.length)
     {
         return(0);
     }
     return(-1);
 }
Example #3
0
 public static void DrawGradientLine(this Texture2D texture, IntSegment2 segment, Color color0, Color color1)
 {
     DrawGradientLine(texture, segment.a, segment.b, color0, color1);
 }
Example #4
0
 public static void DrawLine(this Texture2D texture, IntSegment2 segment, Color color, bool AA = false)
 {
     DrawLine(texture, segment.a, segment.b, color, AA);
 }
Example #5
0
 private static void WuLine(IntSegment2 segment, Action <int, int, float> draw)
 {
     WuLine(segment.a, segment.b, draw);
 }
Example #6
0
 public static void BresenhamLine(IntSegment2 segment, Action <int, int> draw)
 {
     BresenhamLine(segment.a, segment.b, draw);
 }
Example #7
0
 public bool Intersects(IntSegment2 segment, out IntSegment2 intersection, bool testBoundingBox = false)
 {
     return(Intersection.IntSegmentToIntSegment(this, segment, out intersection, testBoundingBox));
 }
Example #8
0
 public IntSegment2(IntSegment2 segment)
 {
     a = segment.a;
     b = segment.b;
 }
Example #9
0
 public static bool IntSegmentToRay(IntSegment2 segment, Ray2D ray, out IntVertex2 intersection)
 {
     return(IntSegmentToRay(segment.a, segment.b, ray, out intersection));
 }
Example #10
0
 public static bool IntPolygonToIntSegment(IntPolygon polygon, IntSegment2 segment)
 {
     return(polygon.segments.Any(s => s.Intersects(segment)));
 }
Example #11
0
        /// <summary>
        /// Based on "Faster Line Segment Intersection" by Franklin Antonio, Graphics Gems III
        /// </summary>
        public static IntersectionType IntSegmentToIntSegmentE(int start0x, int start0y, int end0x, int end0y,
                                                               int start1x, int start1y, int end1x, int end1y, out IntSegment2 intersection, bool testBoundingBox = false)
        {
            intersection = new IntSegment2();
            int ax = end0x - start0x;
            int ay = end0y - start0y;
            int bx = start1x - end1x;
            int by = start1y - end1y;

            if (testBoundingBox)
            {
                // X bound box test
                int x1hi = end0x;
                int x1lo = start0x;
                if (ax < 0)
                {
                    x1lo = end0x;
                    x1hi = start0x;
                }
                if (bx > 0)
                {
                    if (x1hi < end1x || start1x < x1lo)
                    {
                        return(IntersectionType.None);
                    }
                }
                else
                {
                    if (x1hi < start1x || end1x < x1lo)
                    {
                        return(IntersectionType.None);
                    }
                }

                // Y bound box test
                int y1hi = end0y;
                int y1lo = start0y;
                if (ay < 0)
                {
                    y1lo = end0y;
                    y1hi = start0y;
                }
                if (by > 0)
                {
                    if (y1hi < end1y || start1y < y1lo)
                    {
                        return(IntersectionType.None);
                    }
                }
                else
                {
                    if (y1hi < start1y || end1y < y1lo)
                    {
                        return(IntersectionType.None);
                    }
                }
            }

            int cx          = start0x - start1x;
            int cy          = start0y - start1y;
            int denominator = ay * bx - ax * by; // Both denominator

            // Alpha tests
            int alphaNumerator = by * cx - bx * cy;

            if (denominator > 0)
            {
                if (alphaNumerator < 0 || alphaNumerator > denominator)
                {
                    return(IntersectionType.None);
                }
            }
            else
            {
                if (alphaNumerator > 0 || alphaNumerator < denominator)
                {
                    return(IntersectionType.None);
                }
            }
            // Beta tests
            int betaNumerator = ax * cy - ay * cx;

            if (denominator > 0)
            {
                if (betaNumerator < 0 || betaNumerator > denominator)
                {
                    return(IntersectionType.None);
                }
            }
            else
            {
                if (betaNumerator > 0 || betaNumerator < denominator)
                {
                    return(IntersectionType.None);
                }
            }

            // Compute intersection coordinates

            // Segments are parallel
            if (denominator == 0)
            {
                // Segments are noncollinear
                if (alphaNumerator != 0)
                {
                    return(IntersectionType.None);
                }

                // Make sure that start is before end on x axis
                if (start0x > end0x)
                {
                    PGUtils.Swap(ref start0x, ref end0x);
                    PGUtils.Swap(ref start0y, ref end0y);
                }
                if (start1x > end1x)
                {
                    PGUtils.Swap(ref start1x, ref end1x);
                    PGUtils.Swap(ref start1y, ref end1y);
                }

                int biggestStartX = start0x > start1x ? start0x : start1x;
                int smallestEndX  = end0x < end1x ? end0x : end1x;

                // Segments are collinear but not intersecting
                if (biggestStartX > smallestEndX)
                {
                    return(IntersectionType.None);
                }

                // Make sure that start is before end on y axis
                // Remember swap event to prevent mirroring of intersection segment later
                bool swappedY = false;
                if (start0y > end0y)
                {
                    PGUtils.Swap(ref start0x, ref end0x);
                    PGUtils.Swap(ref start0y, ref end0y);
                    swappedY = true;
                }
                if (start1y > end1y)
                {
                    PGUtils.Swap(ref start1x, ref end1x);
                    PGUtils.Swap(ref start1y, ref end1y);
                    swappedY = true;
                }

                int biggestStartY = start0y > start1y ? start0y : start1y;
                int smallestEndY  = end0y < end1y ? end0y : end1y;

                // Segments are collinear but not intersecting
                if (biggestStartY > smallestEndY)
                {
                    return(IntersectionType.None);
                }

                if (swappedY)
                {
                    intersection = new IntSegment2(biggestStartX, smallestEndY, smallestEndX, biggestStartY);
                }
                else
                {
                    intersection = new IntSegment2(biggestStartX, biggestStartY, smallestEndX, smallestEndY);
                }
                return(IntersectionType.Segment);
            }

            int numerator = alphaNumerator * ax;               // Numerator
            int x         = start0x + numerator / denominator; // Intersection x

            numerator = alphaNumerator * ay;
            int y = start0y + numerator / denominator; // Intersection y

            intersection = new IntSegment2(x, y, x, y);
            return(IntersectionType.Point);
        }
Example #12
0
 public static IntersectionType IntSegmentToIntSegmentE(IntVertex2 start0, IntVertex2 end0, IntVertex2 start1,
                                                        IntVertex2 end1, out IntSegment2 intersection, bool testBoundingBox = false)
 {
     return(IntSegmentToIntSegmentE(start0.x, start0.y, end0.x, end0.y, start1.x, start1.y, end1.x, end1.y,
                                    out intersection, testBoundingBox));
 }
Example #13
0
 public static bool IntSegmentToIntSegment(int start0x, int start0y, int end0x, int end0y, int start1x,
                                           int start1y, int end1x, int end1y, out IntSegment2 intersection, bool testBoundingBox = false)
 {
     return(IntSegmentToIntSegmentE(start0x, start0y, end0x, end0y, start1x, start1y, end1x, end1y,
                                    out intersection, testBoundingBox) != IntersectionType.None);
 }
Example #14
0
 public static bool IntSegmentToIntSegment(IntSegment2 segment0, IntSegment2 segment1,
                                           out IntSegment2 intersection, bool testBoundingBox = false)
 {
     return(IntSegmentToIntSegmentE(segment0.a, segment0.b, segment1.a, segment1.b, out intersection,
                                    testBoundingBox) != IntersectionType.None);
 }
Example #15
0
        public static float IntLineSegmentToIntLineSegment(IntSegment2 S1, IntSegment2 S2)
        {
            IntVertex2 u = S1.b - S1.a;
            IntVertex2 v = S2.b - S2.a;
            IntVertex2 w = S1.a - S2.a;
            float      a = IntVertex2.Dot(u, u); // always >= 0
            float      b = IntVertex2.Dot(u, v);
            float      c = IntVertex2.Dot(v, v); // always >= 0
            float      d = IntVertex2.Dot(u, w);
            float      e = IntVertex2.Dot(v, w);
            float      D = a * c - b * b; // always >= 0
            float      sN, sD = D;        // sc = sN / sD, default sD = D >= 0
            float      tN, tD = D;        // tc = tN / tD, default tD = D >= 0

            // compute the line parameters of the two closest points
            if (D < Mathf.Epsilon)
            {
                // the lines are almost parallel
                sN = 0; // force using point P0 on segment S1
                sD = 1; // to prevent possible division by 0.0 later
                tN = e;
                tD = c;
            }
            else
            {
                // get the closest points on the infinite lines
                sN = (b * e - c * d);
                tN = (a * e - b * d);
                if (sN < 0)
                {
                    // sc < 0 => the s=0 edge is visible
                    sN = 0;
                    tN = e;
                    tD = c;
                }
                else if (sN > sD)
                {
                    // sc > 1  => the s=1 edge is visible
                    sN = sD;
                    tN = e + b;
                    tD = c;
                }
            }

            if (tN < 0)
            {
                // tc < 0 => the t=0 edge is visible
                tN = 0;
                // recompute sc for this edge
                if (-d < 0)
                {
                    sN = 0;
                }
                else if (-d > a)
                {
                    sN = sD;
                }
                else
                {
                    sN = -d;
                    sD = a;
                }
            }
            else if (tN > tD)
            {
                // tc > 1  => the t=1 edge is visible
                tN = tD;
                // recompute sc for this edge
                if ((-d + b) < 0)
                {
                    sN = 0;
                }
                else if ((-d + b) > a)
                {
                    sN = sD;
                }
                else
                {
                    sN = (-d + b);
                    sD = a;
                }
            }
            // finally do the division to get sc and tc
            float sc = (Mathf.Abs(sN) < Mathf.Epsilon ? 0 : sN / sD);
            float tc = (Mathf.Abs(tN) < Mathf.Epsilon ? 0 : tN / tD);

            // get the difference of the two closest points
            IntVertex2 dP = w + (sc * u) - (tc * v); // =  S1(sc) - S2(tc)

            return(dP.magnitude);                    // return the closest distance
        }
Example #16
0
 public bool Intersects(IntSegment2 segment)
 {
     return(Intersection.IntPolygonToIntSegment(this, segment));
 }