Example #1
0
        /// <summary>
        /// Returns the closest point on the polyline to the given point.
        /// </summary>
        /// <param name="p">a point</param>
        /// <returns>A point which is the closest to the given point but still on the line.</returns>
        public Point2D ClosestPointTo(Point2D p)
        {
            var minError = double.MaxValue;
            var closest  = default(Point2D);

            for (var i = 0; i < this.VertexCount - 1; i++)
            {
                var segment   = new LineSegment2D(this.points[i], this.points[i + 1]);
                var projected = segment.ClosestPointTo(p);
                var error     = p.DistanceTo(projected);
                if (error < minError)
                {
                    minError = error;
                    closest  = projected;
                }
            }

            return(closest);
        }
Example #2
0
        /// <summary>
        /// Creates a <see cref="Circle2D"/> circle from three points which lie along its circumference.
        /// Points may not be collinear
        /// </summary>
        /// <param name="pointA">The first point on the circle.</param>
        /// <param name="pointB">The second point on the circle.</param>
        /// <param name="pointC">The third point on the circle.</param>
        /// <returns>A Circle which is defined by the three specified points</returns>
        /// <exception cref="ArgumentException">An exception is thrown if no possible circle can be formed from the points</exception>
        public static Circle2D FromPoints(Point2D pointA, Point2D pointB, Point2D pointC)
        {
            // ReSharper disable InconsistentNaming
            var midpointAB = Point2D.MidPoint(pointA, pointB);
            var midpointBC = Point2D.MidPoint(pointB, pointC);
            var gradientAB = (pointB.Y - pointA.Y) / (pointB.X - pointA.X);
            var gradientBC = (pointC.Y - pointB.Y) / (pointC.X - pointB.X);
            var gradientl1 = -1 / gradientAB;
            var gradientl2 = -1 / gradientBC;

            // ReSharper restore InconsistentNaming
            var denominator = gradientl2 - gradientl1;
            var nominator   = midpointAB.Y - (gradientl1 * midpointAB.X) + (gradientl2 * midpointBC.X) - midpointBC.Y;
            var centerX     = nominator / denominator;
            var centerY     = (gradientl1 * (centerX - midpointAB.X)) + midpointAB.Y;
            var center      = new Point2D(centerX, centerY);

            if (double.IsNaN(center.X) || double.IsNaN(center.Y) || double.IsInfinity(center.X) || double.IsInfinity(center.Y))
            {
                throw new ArgumentException("Points cannot form a circle, are they collinear?");
            }

            return(new Circle2D(center, center.DistanceTo(pointA)));
        }