/// <summary>
 ///     Construct line segment with the specified start and end points.
 /// </summary>
 /// <param name="startPoint">The start point.</param>
 /// <param name="endPoint">The end point.</param>
 public DoubleLine(DoublePoint startPoint, DoublePoint endPoint)
 {
     _start = startPoint;
     _end   = endPoint;
 }
 /// <summary>
 ///     Calculates the length of the given line segment.
 /// </summary>
 /// <param name="line">The line segment to measure.</param>
 /// <returns>The length of the line segment.</returns>
 public static double CalculateLineSegmentLength(DoubleLine line)
 {
     return(DoublePoint.CalculateEuclideanDistance(line._start, line._end));
 }
 /// <summary>
 ///     Calculates the euclidean shortest distance between a line segment and point.
 /// </summary>
 /// <param name="line">The line segment involved in the calculation.</param>
 /// <param name="point">The point involved in the calculation.</param>
 /// <returns>The shortest euclidean distance between the given line segment and point.</returns>
 public static double CalculateEuclideanDistanceFromLineToPoint(DoubleLine line, DoublePoint point)
 {
     return(Math.Sqrt(CalculateSquaredDistanceFromLineToPoint(line, point)));
 }
 /// <summary>
 ///     Calculates the squared length of the given line segment.
 /// </summary>
 /// <param name="line">The line segment to measure.</param>
 /// <returns>The squared length of the line segment.</returns>
 public static double CalculateSquaredLineSegmentLength(DoubleLine line)
 {
     return(DoublePoint.CalculateSquaredDistance(line._start, line._end));
 }
        /// <summary>
        ///     Calculates the squared shortest distance between a line segment and point.
        /// </summary>
        /// <param name="line">The line segment involved in the calculation.</param>
        /// <param name="point">The point involved in the calculation.</param>
        /// <returns>The shortest squared distance between the given line segment and point.</returns>
        public static double CalculateSquaredDistanceFromLineToPoint(DoubleLine line, DoublePoint point)
        {
            // Calculate the projection of the given point onto the given line
            var numerator = (point.X - line._start.X) * (line._end.X - line._start.X) +
                            (point.Y - line._start.Y) * (line._end.Y - line._start.Y);
            var denominator = DoublePoint.CalculateSquaredDistance(line._start, line._end);
            var projection  = numerator / denominator;

            // If the projection is beyond the segment, return the distance to
            // either the start or end point on the line segment (whichever
            // happens to be the shortest)
            if (projection < 0 || projection > 1)
            {
                var distanceToStart = DoublePoint.CalculateSquaredDistance(line._start, point);
                var distanceToEnd   = DoublePoint.CalculateSquaredDistance(line._end, point);
                return(distanceToStart < distanceToEnd ? distanceToStart : distanceToEnd);
            }


            // Create a point on the line segment from which to measure the distance to the given point
            var segmentPoint = new DoublePoint(line._start.X + projection * (line._end.X - line._start.X),
                                               line._start.Y + projection * (line._end.Y - line._start.Y));

            // Measure the distance from this point on the segment to the given point
            return(DoublePoint.CalculateSquaredDistance(segmentPoint, point));
        }