Example #1
0
        /// <summary>
        /// Returns a vertex representing the closest point on this line segment from a given vertex
        /// </summary>
        /// <param name="point">The point we want to be close to</param>
        /// <param name="isInfiniteLine">If true treat the line as infinitly long</param>
        /// <param name="endPointFlag">Outputs 0 if the vertex is on the line segment, 1 if beyond P0, 2 if beyong P1 and -1 if P1=P2</param>
        /// <returns>The point on this segment or infinite line that is closest to the given point</returns>
        public Vertex ClosestPointTo(Vertex point, bool isInfiniteLine, out EndPointInteraction endPointFlag)
        {
            // If the points defining this segment are the same, we treat the segment as a point
            // special handling to avoid 0 in denominator later
            if (P2.X == P1.X && P2.Y == P1.Y)
            {
                endPointFlag = EndPointInteraction.P1equalsP2;
                return(P1);
            }

            //http://softsurfer.com/Archive/algorithm_0102/algorithm_0102.htm

            Vector v = ToVector(); // vector from p1 to p2 in the segment

            v.Z = 0;
            Vector w = new Vector(P1.ToCoordinate(), point.ToCoordinate()); // vector from p1 to Point

            w.Z = 0;
            double c1 = w.Dot(v); // the dot product represents the projection onto the line

            if (c1 < 0)
            {
                endPointFlag = EndPointInteraction.PastP1;
                if (!isInfiniteLine) // The closest point on the segment to Point is p1
                {
                    return(P1);
                }
            }

            double c2 = v.Dot(v);

            if (c2 <= c1)
            {
                endPointFlag = EndPointInteraction.PastP2;
                if (!isInfiniteLine) // The closest point on the segment to Point is p2
                {
                    return(P2);
                }
            }

            // The closest point on the segment is perpendicular to the point,
            // but somewhere on the segment between P1 and P2
            endPointFlag = EndPointInteraction.OnLine;
            double b = c1 / c2;

            v = v.Multiply(b);
            Vertex pb = new Vertex(P1.X + v.X, P1.Y + v.Y);

            return(pb);
        }
Example #2
0
        /// <summary>
        /// Returns a vertex representing the closest point on this line segment from a given vertex
        /// </summary>
        /// <param name="point">The point we want to be close to</param>
        /// <param name="isInfiniteLine">If true treat the line as infinitly long</param>
        /// <param name="endPointFlag">Outputs 0 if the vertex is on the line segment, 1 if beyond P0, 2 if beyong P1 and -1 if P1=P2</param>
        /// <returns>The point on this segment or infinite line that is closest to the given point</returns>
        public Vertex ClosestPointTo(Vertex point, bool isInfiniteLine, out EndPointInteraction endPointFlag)
        {
            // If the points defining this segment are the same, we treat the segment as a point
            // special handling to avoid 0 in denominator later
            if (P2.X == P1.X && P2.Y == P1.Y)
            {
                endPointFlag = EndPointInteraction.P1equalsP2;
                return P1;
            }

            //http://softsurfer.com/Archive/algorithm_0102/algorithm_0102.htm

            Vector v = ToVector(); // vector from p1 to p2 in the segment
            v.Z = 0;
            Vector w = new Vector(P1.ToCoordinate(), point.ToCoordinate()); // vector from p1 to Point
            w.Z = 0;
            double c1 = w.Dot(v); // the dot product represents the projection onto the line

            if (c1 < 0)
            {
                endPointFlag = EndPointInteraction.PastP1;
                if (!isInfiniteLine) // The closest point on the segment to Point is p1
                    return P1;
            }

            double c2 = v.Dot(v);

            if (c2 <= c1)
            {
                endPointFlag = EndPointInteraction.PastP2;
                if (!isInfiniteLine) // The closest point on the segment to Point is p2
                    return P2;
            }

            // The closest point on the segment is perpendicular to the point,
            // but somewhere on the segment between P1 and P2
            endPointFlag = EndPointInteraction.OnLine;
            double b = c1 / c2;
            v = v.Multiply(b);
            Vertex pb = new Vertex(P1.X + v.X, P1.Y + v.Y);
            return pb;
        }