Exemple #1
0
        /// <summary>
        /// finds the closest point on a line segment to a given point
        /// </summary>
        /// <param name="point">given point</param>
        /// <param name="edge">line segment</param>
        /// <returns>closest point on line segment</returns>
        public static Vector2 ClosestPointOnEdge(Vector2 point, LineSegment edge)
        {
            // vector of edge
            Vector2 a = edge.Point2 - edge.Point1;

            // vector from initial point of edge to our point
            Vector2 b = point - edge.Point1;

            // scalar projection of b onto a
            float compBOntoA = Vector2.Dot(a, b) / a.Length();

            if (compBOntoA < 0)
                return edge.Point1;
            if (compBOntoA > a.Length())
                return edge.Point2;

            // unit vector of a
            a.Normalize();
            //a = a / a.Length();

            // vector projection of b onto a
            Vector2 projBontoA = a * compBOntoA;

            // vector projection plus initial point of edge
            Vector2 pointOnEdge = edge.Point1 + projBontoA;

            //pointOnEdge.X = MathHelper.Clamp(pointOnEdge.X, edge.Point1.X, edge.Point2.X);
            //pointOnEdge.Y = MathHelper.Clamp(pointOnEdge.Y, edge.Point1.Y, edge.Point2.Y);

            return pointOnEdge;
        }
Exemple #2
0
        public bool ContainsPoint(Vector2 p)
        {
            if (p.X < MinX || p.X > MaxX || p.Y < MinY || p.Y > MaxY)
                return false;

            Vector2 rayStart = new Vector2(MinX - epsilon, p.Y);
            Vector2 rayEnd = p;
            LineSegment ray = new LineSegment(rayStart, rayEnd);

            // Test the ray against all sides
            int intersections = 0;
            foreach (LineSegment side in sides)
            {
                if (Geometry.LineSegmentIntersect(ray, side))
                    intersections++;
            }
            // if odd return true
            if ((intersections & 1) == 1)
                return true;
            // if even return false
            else
                return false;
        }
Exemple #3
0
        // maybe not working
        /*public static bool LineSegmentIntersect(LineSegment line1, LineSegment line2)
        {
            float v1x1 = line1.Point1.X;
            float v1x2 = line1.Point2.X;
            float v1y1 = line1.Point1.Y;
            float v1y2 = line1.Point2.Y;

            float v2x1 = line2.Point1.X;
            float v2x2 = line2.Point2.X;
            float v2y1 = line2.Point1.Y;
            float v2y2 = line2.Point2.Y;

            float d1, d2;
            float a1, a2, b1, b2, c1, c2;

            // Convert vector 1 to a line (line 1) of infinite length.
            // We want the line in linear equation standard form: A*x + B*y + C = 0
            // See: http://en.wikipedia.org/wiki/Linear_equation
            a1 = v1y2 - v1y1;
            //a1 = line1.Point2.Y - line1.Point1.Y;
            b1 = v1x1 - v1x2;
            //b1 = line1.Point1.X - line1.Point2.X;
            c1 = (v1x2 * v1y1) - (v1x1 * v1y2);
            //c1 = (line1.Point2.X * line1.Point1.Y) - (line1.Point1.X * line1.Point2.Y);

            // Every point (x,y), that solves the equation above, is on the line,
            // every point that does not solve it, is either above or below the line.
            // We insert (x1,y1) and (x2,y2) of vector 2 into the equation above.
            d1 = (a1 * v2x1) + (b1 * v2y1) + c1;
            //d1 = (a1 * line2.Point1.X) + (b1 * line2.Point1.Y) + c1;
            d2 = (a1 * v2x2) + (b1 * v2y2) + c1;
            //d2 = (a1 * line2.Point2.X) + (b1 * line2.Point2.Y) + c1;

            // If d1 and d2 both have the same sign, they are both on the same side of
            // our line 1 and in that case no intersection is possible. Careful, 0 is
            // a special case, that's why we don't test ">=" and "<=", but "<" and ">".
            if (d1 > 0 && d2 > 0) return false;
            if (d1 < 0 && d2 < 0) return false;

            // We repeat everything above for vector 2.
            // We start by calculating line 2 in linear equation standard form.
            a2 = v2y2 - v2y1;
            //a2 = line2.Point2.Y - line2.Point1.Y;
            b2 = v2x1 - v2x2;
            //b2 = line2.Point1.X - line2.Point2.X;
            c2 = (v2x2 * v1y1) - (v2x1 * v2y2);
            //c2 = (line2.Point2.X * line1.Point1.Y) - (line2.Point1.X * line2.Point2.Y);

            // Calulate d1 and d2 again, this time using points of vector 1
            d1 = (a2 * v1x1) + (b2 * v1y1) + c2;
            //d1 = (a2 * line1.Point1.X) + (b2 * line1.Point1.Y) + c2;
            d2 = (a2 * v1x2) + (b2 * v1y2) + c2;
            //d2 = (a2 * line1.Point2.X) + (b2 * line1.Point2.Y) + c2;

            // Again, if both have the same sign (and neither one is 0),
            // no intersection is possible.
            if (d1 > 0 && d2 > 0) return false;
            if (d1 < 0 && d2 < 0) return false;

            // If we get here, only three possibilities are left. Either the two
            // vectors intersect in exactly one point or they are collinear
            // (they both lie both on the same infinite line), in which case they
            // may intersect in an infinite number of points or not at all.
            //if ((a1 * b2) - (a2 * b1) == 0.0f) return COLLINEAR;

            // If they are not collinear, they must intersect in exactly one point.
            return true;
        }*/
        // might work
        public static bool LineSegmentIntersect(LineSegment line1, LineSegment line2)
        {
            // Find the four orientations needed for general and
            // special cases
            int o1 = orientation(line1.Point1, line1.Point2, line2.Point1);
            int o2 = orientation(line1.Point1, line1.Point2, line2.Point2);
            int o3 = orientation(line2.Point1, line2.Point2, line1.Point1);
            int o4 = orientation(line2.Point1, line2.Point2, line1.Point2);

            // General case
            if (o1 != o2 && o3 != o4)
                return true;

            return false;
        }
Exemple #4
0
        public static LineSegment PointLinePerpendicular(Vector2 point, LineSegment line)
        {
            // vector of line
            Vector2 a = line.Point2 - line.Point1;

            // vector of point from initial point on line
            Vector2 b = point - line.Point1;

            // scalar projection of b onto a
            float compBOntoA = Vector2.Dot(a, b) / a.Length();

            // unit vector of a
            a = a / a.Length();

            // vector projection of b onto a
            Vector2 projBontoA = a * compBOntoA;

            // vector projection plus initial point of edge
            Vector2 pointOnEdge = line.Point1 + projBontoA;

            // return line from point on line to given point
            return new LineSegment(pointOnEdge, point);
        }
Exemple #5
0
        /// <summary>
        /// finds the closest point on a polygon to a given point
        /// </summary>
        /// <param name="point">given point</param>
        /// <param name="polygon">polygon</param>
        /// <param name="closestEdge">edge the point is on</param>
        /// <returns>closest point on polygon</returns>
        public static Vector2 ClosestPointOnPolygon(Vector2 point, Polygon polygon, ref LineSegment closestEdge)
        {
            Vector2 closestPoint = Vector2.Zero;
            float closestDistance = float.MaxValue;

            foreach (LineSegment side in polygon.Sides)
            {
                Vector2 pointOnEdge = ClosestPointOnEdge(point, side);

                float distance = Vector2.DistanceSquared(point, pointOnEdge);
                if (distance < closestDistance)
                {
                    closestPoint = pointOnEdge;
                    closestDistance = distance;
                    closestEdge = side;
                }
            }

            return closestPoint;
        }