Beispiel #1
0
        // http://stackoverflow.com/a/100165/925777
        public static bool Intersects(Segment2D segment, RectangleF rectangle)
        {
            float minX = Math.Min(segment.Start.X, segment.End.X);
            float maxX = Math.Max(segment.Start.X, segment.End.X);

            if (maxX > rectangle.Right)
            {
                maxX = rectangle.Right;
            }

            if (minX < rectangle.Left)
            {
                minX = rectangle.Left;
            }

            if (minX > maxX)
            {
                return false;
            }

            float minY = Math.Min(segment.Start.Y, segment.End.Y);
            float maxY = Math.Max(segment.Start.Y, segment.End.Y);

            float dx = segment.End.X - segment.Start.X;
            if (Math.Abs(dx) > 0.0000001f)
            {
                float a = (segment.End.Y - segment.Start.Y) / dx;
                float b = segment.Start.Y - a * segment.Start.X;
                minY = a * minX + b;
                maxY = a * maxX + b;
            }

            if (minY > maxY)
            {
                float tmp = maxY;
                maxY = minY;
                minY = tmp;
            }

            if (maxY > rectangle.Bottom)
            {
                maxY = rectangle.Bottom;
            }

            if (minY < rectangle.Top)
            {
                minY = rectangle.Top;
            }

            if (minY > maxY)
            {
                return false;
            }

            return true;
        }
Beispiel #2
0
 public static float MinimumDistance(Segment2D segment, Vector2 point)
 {
     Vector2 minimumDistancePoint;
     return Segment2D.MinimumDistance(segment, point, out minimumDistancePoint);
 }
Beispiel #3
0
 public static bool Intersects(Segment2D segment1, Segment2D segment2)
 {
     Vector2 intersectionPoint;
     return Segment2D.Intersects(segment1, segment2, out intersectionPoint);
 }
Beispiel #4
0
        public static bool Intersects(Segment2D segment1, Segment2D segment2, out Vector2 intersectionPoint)
        {
            /*  const float Epsilon = 0.00001f;

              Vector2 cmp = new Vector2(segment2.Start.X - segment1.Start.X, segment2.Start.Y - segment1.Start.Y);
              Vector2 r = new Vector2(segment1.End.X - segment1.Start.X, segment1.End.Y - segment1.Start.Y);
              Vector2 s = new Vector2(segment2.End.X - segment2.Start.X, segment2.End.Y - segment2.Start.Y);

              float cmPxR = cmp.X * r.Y - cmp.Y * r.X;
              float cmPxS = cmp.X * s.Y - cmp.Y * s.X;
              float RxS = r.X * s.Y - r.Y * s.X;

              if (Math.Abs(cmPxR) < Epsilon)
              {
                  intersectionPoint = Vector2.Zero;
                  return true;
              }

              if (Math.Abs(RxS) < Epsilon)
              {
                  intersectionPoint = default(Vector2);
                  return false;
              }

              float rXsR = 1f / RxS;
              float t = cmPxS * rXsR;
              float u = cmPxR * rXsR;

              if (t >= 0f && t <= 1f && u >= 0f && u <= 1f)
              {
                  intersectionPoint = segment1.Start + r * t;
                  return true;
              }

              intersectionPoint = default(Vector2);
              return false; */

            const float Epsilon = 0.00001f;

            float ua = (segment2.End.X - segment2.Start.X) * (segment1.Start.Y - segment2.Start.Y) - (segment2.End.Y - segment2.Start.Y) * (segment1.Start.X - segment2.Start.X);
            float ub = (segment1.End.X - segment1.Start.X) * (segment1.Start.Y - segment2.Start.Y) - (segment1.End.Y - segment1.Start.Y) * (segment1.Start.X - segment2.Start.X);
            float denominator = (segment2.End.Y - segment2.Start.Y) * (segment1.End.X - segment1.Start.X) - (segment2.End.X - segment2.Start.X) * (segment1.End.Y - segment1.Start.Y);

            if (Math.Abs(denominator) <= Epsilon)
            {
                if (Math.Abs(ua) <= Epsilon && Math.Abs(ub) <= Epsilon)
                {
                    intersectionPoint = (segment1.Start + segment1.End + segment2.Start + segment2.End) / 4f;
                    return true;
                }
            }
            else
            {
                ua /= denominator;
                ub /= denominator;

                if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1)
                {
                    intersectionPoint = new Vector2
                    {
                        X = segment1.Start.X + ua * (segment1.End.X - segment1.Start.X),
                        Y = segment1.Start.Y + ua * (segment1.End.Y - segment1.Start.Y)
                    };
                    return true;
                }
            }

            intersectionPoint = default(Vector2);
            return false;
        }
Beispiel #5
0
        public static Segment2D Clamp(Segment2D segment, RectangleF area)
        {
            segment.Start = Vector2.Clamp(segment.Start, area.TopLeft, area.BottomRight);
            segment.End = Vector2.Clamp(segment.End, area.TopLeft, area.BottomRight);

            return segment;
        }
Beispiel #6
0
 public static bool Intersects(Segment2D segment, Circle circle)
 {
     return(Segment2D.MinimumDistance(segment, circle.Position) < circle.Radius);
 }
Beispiel #7
0
        //  public static float MinimumDistance(Segment2D segment, RectangleF rectangle, out Vector2 minimumDistancePoint)

        // is this correct? i guess so...
        public static float MaximumDistance(Segment2D segment, Vector2 point)
        {
            return(Math.Max(Vector2.Distance(segment.Start, point), Vector2.Distance(segment.End, point)));
        }
Beispiel #8
0
    //  public static float MinimumDistance(Segment2D segment, RectangleF rectangle, out Vector2 minimumDistancePoint)

        // is this correct? i guess so...
        public static float MaximumDistance(Segment2D segment, Vector2 point)
        {
            return Math.Max(Vector2.Distance(segment.Start, point), Vector2.Distance(segment.End, point));
        }
Beispiel #9
0
        // http://stackoverflow.com/a/100165/925777
        public static bool Intersects(Segment2D segment, RectangleF rectangle)
        {
            return(Segment2D.Intersects(segment, rectangle.LeftSegment) ||
                   Segment2D.Intersects(segment, rectangle.TopSegment) ||
                   Segment2D.Intersects(segment, rectangle.RightSegment) ||
                   Segment2D.Intersects(segment, rectangle.BottomSegment) ||
                   (rectangle.Contains(segment.Start) && rectangle.Contains(segment.End)));

            float minX = Math.Min(segment.Start.X, segment.End.X);
            float maxX = Math.Max(segment.Start.X, segment.End.X);

            if (maxX > rectangle.Right)
            {
                maxX = rectangle.Right;
            }

            if (minX < rectangle.Left)
            {
                minX = rectangle.Left;
            }

            if (minX > maxX)
            {
                return(false);
            }

            float minY = Math.Min(segment.Start.Y, segment.End.Y);
            float maxY = Math.Max(segment.Start.Y, segment.End.Y);

            float dx = segment.End.X - segment.Start.X;

            if (Math.Abs(dx) > 0.0000001f)
            {
                float a = (segment.End.Y - segment.Start.Y) / dx;
                float b = segment.Start.Y - a * segment.Start.X;
                minY = a * minX + b;
                maxY = a * maxX + b;
            }

            if (minY > maxY)
            {
                float tmp = maxY;
                maxY = minY;
                minY = tmp;
            }

            if (maxY > rectangle.Bottom)
            {
                maxY = rectangle.Bottom;
            }

            if (minY < rectangle.Top)
            {
                minY = rectangle.Top;
            }

            if (minY > maxY)
            {
                return(false);
            }

            return(true);
        }
Beispiel #10
0
        public static float MinimumDistance(Segment2D segment, Vector2f point)
        {
            Vector2f minimumDistancePoint;

            return(Segment2D.MinimumDistance(segment, point, out minimumDistancePoint));
        }
Beispiel #11
0
        public static bool Intersects(Segment2D segment1, Segment2D segment2, out Vector2f intersectionPoint)
        {
            /*  const float Epsilon = 0.00001f;
             *
             * Vector2 cmp = new Vector2(segment2.Start.X - segment1.Start.X, segment2.Start.Y - segment1.Start.Y);
             * Vector2 rectangle = new Vector2(segment1.End.X - segment1.Start.X, segment1.End.Y - segment1.Start.Y);
             * Vector2 s = new Vector2(segment2.End.X - segment2.Start.X, segment2.End.Y - segment2.Start.Y);
             *
             * float cmPxR = cmp.X * rectangle.Y - cmp.Y * rectangle.X;
             * float cmPxS = cmp.X * s.Y - cmp.Y * s.X;
             * float RxS = rectangle.X * s.Y - rectangle.Y * s.X;
             *
             * if (Math.Abs(cmPxR) < Epsilon)
             * {
             *    intersectionPoint = Vector2.Zero;
             *    return true;
             * }
             *
             * if (Math.Abs(RxS) < Epsilon)
             * {
             *    intersectionPoint = default(Vector2);
             *    return false;
             * }
             *
             * float rXsR = 1f / RxS;
             * float t = cmPxS * rXsR;
             * float u = cmPxR * rXsR;
             *
             * if (t >= 0f && t <= 1f && u >= 0f && u <= 1f)
             * {
             *    intersectionPoint = segment1.Start + rectangle * t;
             *    return true;
             * }
             *
             * intersectionPoint = default(Vector2);
             * return false; */

            const float Epsilon = 0.00001f;

            float ua          = (segment2.End.X - segment2.Start.X) * (segment1.Start.Y - segment2.Start.Y) - (segment2.End.Y - segment2.Start.Y) * (segment1.Start.X - segment2.Start.X);
            float ub          = (segment1.End.X - segment1.Start.X) * (segment1.Start.Y - segment2.Start.Y) - (segment1.End.Y - segment1.Start.Y) * (segment1.Start.X - segment2.Start.X);
            float denominator = (segment2.End.Y - segment2.Start.Y) * (segment1.End.X - segment1.Start.X) - (segment2.End.X - segment2.Start.X) * (segment1.End.Y - segment1.Start.Y);

            if (Math.Abs(denominator) <= Epsilon)
            {
                if (Math.Abs(ua) <= Epsilon && Math.Abs(ub) <= Epsilon)
                {
                    intersectionPoint = (segment1.Start + segment1.End + segment2.Start + segment2.End) / 4f;
                    return(true);
                }
            }
            else
            {
                ua /= denominator;
                ub /= denominator;

                if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1)
                {
                    intersectionPoint = new Vector2f
                    {
                        X = segment1.Start.X + ua * (segment1.End.X - segment1.Start.X),
                        Y = segment1.Start.Y + ua * (segment1.End.Y - segment1.Start.Y)
                    };
                    return(true);
                }
            }

            intersectionPoint = default(Vector2);
            return(false);
        }
Beispiel #12
0
        public static bool Intersects(Segment2D segment1, Segment2D segment2)
        {
            Vector2f intersectionPoint;

            return(Segment2D.Intersects(segment1, segment2, out intersectionPoint));
        }
Beispiel #13
0
 public static bool Intersects(Vector2f p1, Vector2f p2, Vector2f p3, Vector2f p4, out Vector2f intersectionPoint)
 {
     return(Segment2D.Intersects(new Segment2D(p1, p2), new Segment2D(p3, p4), out intersectionPoint));
 }
Beispiel #14
0
        public static float MinimumDistance(Segment2D segment, Vector2 point, out Vector2 minimumDistancePoint)
        {
            // Return minimum distance between line segment vw and point p
            float lengthSquared = segment.LengthSquared();  // i.e. |w-v|^2 -  avoid a sqrt
            if (lengthSquared == 0.0f)
            {
                minimumDistancePoint = segment.Start;
                return Vector2.Distance(point, segment.Start);   // v == w case
            }

            // Consider the line extending the segment, parameterized as v + t (w - v).
            // We find projection of point p onto the line. 
            // It falls where t = [(p-v) . (w-v)] / |w-v|^2
            float t = Vector2.Dot(point - segment.Start, segment.End - segment.Start) / lengthSquared;
            if (t < 0.0)
            {
                minimumDistancePoint = segment.Start;
                return Vector2.Distance(point, segment.Start);       // Beyond the 'v' end of the segment
            }
            else if (t > 1.0)
            {
                minimumDistancePoint = segment.End;
                return Vector2.Distance(point, segment.End);  // Beyond the 'w' end of the segment
            }

            Vector2 projection = segment.Start + t * (segment.End - segment.Start);  // Projection falls on the segment

            minimumDistancePoint = projection;
            return Vector2.Distance(point, projection);
        }
Beispiel #15
0
 public bool Contains(Segment2D segment)
 {
     return(this.Contains(segment.Start) && this.Contains(segment.End));
 }
Beispiel #16
0
        public static float MinimumDistance(Segment2D segment, Circle circle)
        {
            if (Segment2D.Intersects(segment, circle))
            {
                return 0;
            }

            // okay this Max *should be* unnecessary, but lets keep it just for sure
            return FlaiMath.Max(0, Segment2D.MinimumDistance(segment, circle.Position) - circle.Radius); 
        }
Beispiel #17
0
 public bool Equals(Segment2D other)
 {
     return this.Start == other.Start && this.End == other.End;
 }
Beispiel #18
0
        // is this accurate? could be...
        public static float MaximumDistance(Segment2D segment, RectangleF rectangle)
        {
            if (Segment2D.Intersects(segment, rectangle))
            {
                return 0;
            }

            return FlaiMath.Max(
                Segment2D.MaximumDistance(segment, rectangle.TopLeft), Segment2D.MaximumDistance(segment, rectangle.TopRight),
                Segment2D.MaximumDistance(segment, rectangle.BottomLeft), Segment2D.MaximumDistance(segment, rectangle.BottomRight));
        }
Beispiel #19
0
 public static bool Intersects(Segment2D segment, Circle circle)
 {
     return Segment2D.MinimumDistance(segment, circle.Position) < circle.Radius;
 }
        public static IEnumerable<Vector2i> GetPointsOnSegment(Segment2D segment)
        {
            yield return new Vector2i(segment.Start);
            if (segment.IsPoint || new Vector2i(segment.Start) == new Vector2i(segment.End))
            {
                yield break;
            }


            float slope = segment.Slope;
            if (float.IsInfinity(slope)) // Segment is straight line in x-axis
            {
                int x = (int)segment.Start.X;

                int start = (int)FlaiMath.Min(segment.Start.Y, segment.End.Y);
                int end = (int)FlaiMath.Max(segment.Start.Y, segment.End.Y);
                for (int y = start + 1; y <= end; y++)
                {
                    yield return new Vector2i(x, y);
                }
            }
            else
            {
                Vector2 normalizedStep = Vector2.Normalize(segment.End - segment.Start);

                float xStep = normalizedStep.X;
                float yStep = normalizedStep.Y;

                Vector2i previousCellIndex = Vector2i.One * int.MaxValue;
                Vector2 currentPosition = segment.Start;
                while (true)
                {
                    float nextXDistance = float.MaxValue;
                    if (xStep > 0)
                    {
                        float xDist = FlaiMath.Floor(currentPosition.X + 1) - currentPosition.X;
                        nextXDistance = xDist / xStep;
                    }
                    else if (xStep < 0)
                    {
                        float xDist = FlaiMath.Floor(currentPosition.X) - currentPosition.X;
                        nextXDistance = xDist / xStep;
                    }

                    if (nextXDistance == 0)
                    {
                        nextXDistance = float.MaxValue;
                    }

                    float nextYDistance = float.MaxValue;
                    if (yStep > 0)
                    {
                        float yDist = FlaiMath.Floor(currentPosition.Y + 1) - currentPosition.Y;
                        nextYDistance = yDist / yStep;
                    }
                    else if (yStep < 0)
                    {
                        float yDist = FlaiMath.Floor(currentPosition.Y) - currentPosition.Y;
                        nextYDistance = yDist / yStep;
                    }

                    if (nextYDistance == 0)
                    {
                        nextYDistance = float.MaxValue;
                    }

                    // Vector2i previousCellIndex = new Vector2i(currentPosition);
                    if (FlaiMath.Distance(nextXDistance, nextYDistance) < 0.0001f)
                    {
                        float newX = xStep > 0 ? (int)currentPosition.X + 1 : FlaiMath.Decrement((int)currentPosition.X);
                        float newY = yStep > 0 ? (int)currentPosition.Y + 1 : FlaiMath.Decrement((int)currentPosition.Y);
                        currentPosition = new Vector2(newX, newY);
                    }
                    else if (nextXDistance < nextYDistance)
                    {
                        if (xStep > 0)
                        {
                            currentPosition = new Vector2((int)currentPosition.X + 1, currentPosition.Y + normalizedStep.Y * nextXDistance);
                        }
                        else
                        {
                            currentPosition = new Vector2(FlaiMath.Decrement((int)currentPosition.X), currentPosition.Y + normalizedStep.Y * nextXDistance);
                        }
                    }
                    else
                    {
                        if (yStep > 0)
                        {
                            currentPosition = new Vector2(currentPosition.X + normalizedStep.X * nextYDistance, (int)currentPosition.Y + 1);
                        }
                        else
                        {
                            currentPosition = new Vector2(currentPosition.X + normalizedStep.X * nextYDistance, FlaiMath.Decrement((int)currentPosition.Y));
                        }
                    }

                    currentPosition = Vector2.Clamp(currentPosition, Vector2.Min(segment.Start, segment.End), Vector2.Max(segment.Start, segment.End));

                    Vector2i currentCellIndex = new Vector2i(currentPosition);
                    yield return currentCellIndex;

                    if (currentCellIndex == new Vector2i(segment.End) || Vector2.Distance(segment.Start, currentPosition) > Vector2.Distance(segment.Start, segment.End) || currentCellIndex == previousCellIndex)
                    {
                        yield break;
                    }

                    previousCellIndex = currentCellIndex;
                }
            }
        }
Beispiel #21
0
 public bool Equals(Segment2D other)
 {
     return(this.Start == other.Start && this.End == other.End);
 }