Пример #1
0
        public override bool Equals(Object obj)
        {
            // Check for null values and compare run-time types.
            if (obj == null || GetType() != obj.GetType())
            {
                return(false);
            }
            LineSegment2D l = (LineSegment2D)obj;

            return(Start == l.Start && End == l.End);
        }
Пример #2
0
        /**
         * Returns 1 if inside, 0 if intersecting and -1 outside.
         */
        public LineRelation DescribeRelation(LineSegment2D line)
        {
            //int x1, int y1, int x2, int y2,
            float xmax = X + Width;
            float ymax = Y + Height;

            float u1 = 0.0f;
            float u2 = 1.0f;

            float deltaX = (line.End.X - line.Start.X);
            float deltaY = (line.End.Y - line.Start.Y);

            /*
             * left edge, right edge, bottom edge and top edge checking
             */
            float[] pPart = { -deltaX, deltaX, -deltaY, deltaY };
            float[] qPart = { line.Start.X - X, xmax - line.Start.X, line.Start.Y - Y, ymax - line.Start.Y };

            for (int i = 0; i < 4; i++)
            {
                float p = pPart[i];
                float q = qPart[i];

                if (p == 0 && q < 0)
                {
                    return(LineRelation.LINE_OUTSIDE);
                }

                float r = q / p;

                if (p < 0)
                {
                    u1 = Math.Max(u1, r);
                }
                else if (p > 0)
                {
                    u2 = Math.Min(u2, r);
                }

                if (u1 > u2)
                {
                    return(LineRelation.LINE_OUTSIDE);
                }
            }

            if (u2 < 1 || u1 < 1)
            {
                return(LineRelation.LINE_INTERSECTS);
            }
            else
            {
                return(LineRelation.LINE_INSIDE);
            }
        }
Пример #3
0
        public float DistanceSquared(LineSegment2D line)
        {
            //snap the 4 corners to the line and form delta
            Vector2D d1     = line.SnapDelta(TopLeft);
            Vector2D d2     = line.SnapDelta(TopRight);
            Vector2D d3     = line.SnapDelta(BottomLeft);
            Vector2D d4     = line.SnapDelta(BottomRight);
            float    xLower = Math.Min(Math.Min(d1.X, d2.X), Math.Min(d3.X, d4.X));
            float    xUpper = Math.Max(Math.Max(d1.X, d2.X), Math.Max(d3.X, d4.X));
            float    dX     = (xUpper * xLower < 0) ? 0 : Math.Min(Math.Abs(xLower), Math.Abs(xUpper)); //if not all on the same side distance along X axis is 0

            float yLower = Math.Min(Math.Min(d1.Y, d2.Y), Math.Min(d3.Y, d4.Y));
            float yUpper = Math.Max(Math.Max(d1.Y, d2.Y), Math.Max(d3.Y, d4.Y));
            float dY     = (yUpper * yLower < 0) ? 0 : Math.Min(Math.Abs(yLower), Math.Abs(yUpper)); //if not all on the same side distance along Y axis is 0

            return(dX * dX + dY * dY);
        }
Пример #4
0
        public float DistanceSquared(LineSegment2D other)
        {
            //see IsIntersecting...
            Vector2D v  = StartToEnd;
            Vector2D ov = other.StartToEnd;
            Vector2D s  = Start - other.Start;

            float denom = v.Cross(ov);

            if (denom == 0) //lines are parallel
            {
                float d = Direction.OrthogonalizedClockwise().Dot(s);
                return(d * d);
            }

            float a = CgMath.Saturate(ov.Cross(s) / denom);
            float b = CgMath.Saturate(v.Cross(s) / denom);

            return(Math.Min(other.DistanceSquared(Sample(a)), this.DistanceSquared(other.Sample(b))));
        }
Пример #5
0
        public bool Overlaps(LineSegment2D line)
        {
            //same aproach as distance to line segment but simplified
            //snap the 4 corners to the line and form delta
            Vector2D d1 = line.SnapDelta(TopLeft);
            Vector2D d2 = line.SnapDelta(TopRight);
            Vector2D d3 = line.SnapDelta(BottomLeft);
            Vector2D d4 = line.SnapDelta(BottomRight);

            if (CgMath.Sign(d1.X, d2.X, d3.X, d4.X) == 0)//mixed signs
            {
                return(true);
            }

            if (CgMath.Sign(d1.Y, d2.Y, d3.Y, d4.Y) == 0)//mixed signs
            {
                return(true);
            }

            return(false);
        }
Пример #6
0
        /**
         * Get information on how the two lines interact.
         */
        public Relation GetRelation(LineSegment2D other, float tolerance = 0)
        {
            //see IsIntersecting...
            Vector2D v  = StartToEnd;
            Vector2D ov = other.StartToEnd;
            Vector2D s  = Start - other.Start;

            float denom = v.Cross(ov);
            float a     = ov.Cross(s) / denom;
            float b     = v.Cross(s) / denom;

            Relation result = Relation.NoConnection;

            if (Math.Abs(a - 1) < tolerance && (b >= 0 && b <= 1)) //touching - a is 1 and b in range
            {
                result = result | Relation.EndConnects;
            }
            if (Math.Abs(a) < tolerance && (b >= 0 && b <= 1)) //touching - a is 0 and b in range
            {
                result = result | Relation.StartConnects;
            }
            if (Math.Abs(b) < tolerance && (a >= 0 && a <= 1)) //touching - b is 1 and a in range
            {
                result = result | Relation.OtherStartConnects;
            }
            if (Math.Abs(b - 1) < tolerance && (a >= 0 && a <= 1)) //touching - b is 0 and a in range
            {
                result = result | Relation.OtherEndConnects;
            }
            if (a > tolerance && (a - 1) < tolerance && b > tolerance && (b - 1) < tolerance)
            {
                result = result | Relation.Intersection;
            }

            return(result);
        }
Пример #7
0
        /**
         * Constrains a linesegment to fit in the rectangle. Uses Liang Barsky Algorithm.
         * Returns reference to the passed input argument after clipping or null if no portion of the line is within the rectangle.
         */
        public LineSegment2D Clip(LineSegment2D line)
        {
            //int x1, int y1, int x2, int y2,
            Vector2D max   = BottomRight;
            Vector2D start = line.Start;
            Vector2D delta = line.StartToEnd;

            float u1 = 0.0f;
            float u2 = 1.0f;

            if (delta.X == 0 && (start.X < X || start.X > max.X))
            {
                return(LineSegment2D.Void);
            }

            if (delta.Y == 0 && (start.Y < Y || start.Y > max.Y))
            {
                return(LineSegment2D.Void);
            }

            //ugly but optimized
            //left
            float r = (start.X - X) / (-delta.X);

            if (delta.X > 0)
            {
                u1 = Math.Max(u1, r);
            }
            else if (delta.X < 0)
            {
                u2 = Math.Min(u2, r);
            }
            if (u1 > u2)
            {
                return(LineSegment2D.Void);
            }

            //right
            r = (max.X - start.X) / delta.X;
            if (delta.X < 0)
            {
                u1 = Math.Max(u1, r);
            }
            else if (delta.X > 0)
            {
                u2 = Math.Min(u2, r);
            }
            if (u1 > u2)
            {
                return(LineSegment2D.Void);
            }

            //top
            r = (start.Y - Y) / -delta.Y;
            if (delta.Y > 0)
            {
                u1 = Math.Max(u1, r);
            }
            else if (delta.Y < 0)
            {
                u2 = Math.Min(u2, r);
            }
            if (u1 > u2)
            {
                return(LineSegment2D.Void);
            }

            //bottom
            r = (max.Y - start.Y) / delta.Y;
            if (delta.Y < 0)
            {
                u1 = Math.Max(u1, r);
            }
            else if (delta.Y > 0)
            {
                u2 = Math.Min(u2, r);
            }
            if (u1 > u2)
            {
                return(LineSegment2D.Void);
            }

            //clip
            if (u2 < 1)
            {
                line.End = start + u2 * delta;
            }

            if (u1 > 0)
            {
                line.Start = start + u1 * delta;
            }

            return(line);
        }
Пример #8
0
 public float Distance(LineSegment2D line)
 {
     return((float)Math.Sqrt(DistanceSquared(line)));
 }
Пример #9
0
 /**
  * Returns a new vector v at the position where the lines would intersect. Segment boundaries are not considered.
  */
 public Vector2D Intersect(LineSegment2D other)
 {
     return(Start + StartToEnd * GetIntersectionRatio(other));
 }
Пример #10
0
 /**
  * Compare this line segment to another and return true if the lines are parallel.
  */
 public bool IsParallel(LineSegment2D other, float tolerance = 0)
 {
     return(Math.Abs(StartToEnd.Cross(other.StartToEnd)) <= tolerance);
 }