Example #1
0
        public bool Intersection(Segment2d segment, out Vector2d intersection, out Segment2d seg)
        {
            var x1 = A.X;
            var y1 = A.Y;
            var x2 = B.X;
            var y2 = B.Y;
            var x3 = segment.A.X;
            var y3 = segment.A.Y;
            var x4 = segment.B.X;
            var y4 = segment.B.Y;

            var denom = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);

            if (Math.Abs(denom) > float.Epsilon)
            {
                var t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / denom;
                var u = ((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / -denom;

                if (Vec.InOpenRange(t, 0, 1) && Vec.InOpenRange(u, 0, 1))
                {
                    intersection = new Vector2d(
                        x1 + t * (x2 - x1),
                        y1 + t * (y2 - y1)
                        );

                    seg = NaN;
                    return(true);
                }
            }
            else
            {
                var onSegment = new SortedSet <Vector2d>(new OriginComparer());

                var o1 = Vec.CheckOrientation(segment.A, A, B);
                var o2 = Vec.CheckOrientation(segment.B, A, B);
                var o3 = Vec.CheckOrientation(A, segment.A, segment.B);
                var o4 = Vec.CheckOrientation(B, segment.A, segment.B);

                //shit code
                if (o1 == Orientation.ON_SEGMENT)
                {
                    onSegment.Add(segment.A);
                }
                if (o2 == Orientation.ON_SEGMENT)
                {
                    onSegment.Add(segment.B);
                }
                if (o3 == Orientation.ON_SEGMENT)
                {
                    onSegment.Add(A);
                }
                if (o4 == Orientation.ON_SEGMENT)
                {
                    onSegment.Add(B);
                }

                var or = new[] { o1, o2, o3, o4 };

                if (o1 == o2 && o2 == o3 & o3 == o4 && o4 == Orientation.ONLINE)
                {
                    intersection = Vector2d.NaN;
                    seg          = NaN;
                    return(false);
                }

                if (o1 == o2 && o2 == o3 & o3 == o4 && o4 == Orientation.ON_SEGMENT)
                {
                    intersection = Vector2d.NaN;
                    seg          = segment;
                    return(true);
                }

                if (or.Any(n => n == Orientation.LEFT || n == Orientation.RIGHT))
                {
                    intersection = Vector2d.NaN;
                    seg          = NaN;
                    return(false);
                }


                if (onSegment.Count == 1)
                {
                    intersection = onSegment.First();
                    seg          = NaN;
                    return(true);
                }

                if (onSegment.Count > 1)
                {
                    var    arr     = onSegment.ToArray();
                    double minDist = double.MaxValue; // don't need
                    var    a       = Vector2d.NaN;
                    var    b       = Vector2d.NaN;

                    for (int i = 0; i < arr.Length - 1; i++)
                    {
                        var cur  = (i + 1) % onSegment.Count;
                        var next = (cur + 1) % onSegment.Count;

                        //govno code
                        var sqrDist = arr[cur].SqrDist(arr[next]);

                        if (sqrDist < minDist)
                        {
                            minDist = sqrDist;
                            a       = arr[cur];
                            b       = arr[next];
                        }
                    }

                    intersection = Vector2d.NaN;
                    seg          = new Segment2d(a, b);
                    return(true);
                }
            }

            intersection = Vector2d.NaN;
            seg          = NaN;
            return(false);
        }