Nez.Portable/Math/Bezier.cs
/// <summary>
/// recursively subdivides a bezier curve until distanceTolerance is met. Flat sections will have less points then curved with this
/// algorithm.
/// 
/// This image defines the midpoints calculated and makes the variable names sensical:
/// http://www.antigrain.com/research/adaptive_bezier/bezier09.gif
/// based on http://www.antigrain.com/research/adaptive_bezier/index.html
/// </summary>
/// <param name="start">Start.</param>
/// <param name="firstCtrlPoint">First ctrl point.</param>
/// <param name="secondCtrlPoint">Second ctrl point.</param>
/// <param name="end">End.</param>
/// <param name="points">Points.</param>
/// <param name="distanceTolerance">Distance tolerance.</param>
recursively subdivides a bezier curve until distanceTolerance is met. Flat sections will have less points then curved with this
algorithm.


recursively subdivides a bezier curve until distanceTolerance is met . Flat sections will have less points then curved with this algorithm .
static void recursiveGetOptimizedDrawingPoints(
            Vector2 start,
            Vector2 firstCtrlPoint,
            Vector2 secondCtrlPoint,
            Vector2 end,
            List<Vector2> points,
            float distanceTolerance)
        {
            var pt12 = (start + firstCtrlPoint) / 2;
            var pt23 = (firstCtrlPoint + secondCtrlPoint) / 2;
            var pt34 = (secondCtrlPoint + end) / 2;
            var pt123 = (pt12 + pt23) / 2;
            var pt234 = (pt23 + pt34) / 2;
            var pt1234 = (pt123 + pt234) / 2;
            var deltaLine = end - start;
            var d2 = System.Math.Abs(
                (firstCtrlPoint.X - end.X) * deltaLine.Y - (firstCtrlPoint.Y - end.Y) * deltaLine.X);
            var d3 = System.Math.Abs(
                (secondCtrlPoint.X - end.X) * deltaLine.Y - (secondCtrlPoint.Y - end.Y) * deltaLine.X);
            if ((d2 + d3) * (d2 + d3) < distanceTolerance * (deltaLine.X * deltaLine.X + deltaLine.Y * deltaLine.Y))
            {
                points.Add(pt1234);
                return;
            }
            recursiveGetOptimizedDrawingPoints(start, pt12, pt123, pt1234, points, distanceTolerance);
            recursiveGetOptimizedDrawingPoints(pt1234, pt234, pt34, end, points, distanceTolerance);
        }
static void recursiveGetOptimizedDrawingPoints ( Vector2 start , Vector2 firstCtrlPoint , Vector2 secondCtrlPoint , Vector2 end , List < Vector2 > points , float distanceTolerance ) { var pt12 = ( start + firstCtrlPoint ) / 2 ; var pt23 = ( firstCtrlPoint + secondCtrlPoint ) / 2 ; var pt34 = ( secondCtrlPoint + end ) / 2 ; var pt123 = ( pt12 + pt23 ) / 2 ; var pt234 = ( pt23 + pt34 ) / 2 ; var pt1234 = ( pt123 + pt234 ) / 2 ; var deltaLine = end - start ; var d2 = System . Math . Abs ( ( firstCtrlPoint . X - end . X ) * deltaLine . Y - ( firstCtrlPoint . Y - end . Y ) * deltaLine . X ) ; var d3 = System . Math . Abs ( ( secondCtrlPoint . X - end . X ) * deltaLine . Y - ( secondCtrlPoint . Y - end . Y ) * deltaLine . X ) ; if ( ( d2 + d3 ) * ( d2 + d3 ) < distanceTolerance * ( deltaLine . X * deltaLine . X + deltaLine . Y * deltaLine . Y ) ) { points . Add ( pt1234 ) ; return ; } recursiveGetOptimizedDrawingPoints ( start , pt12 , pt123 , pt1234 , points , distanceTolerance ) ; recursiveGetOptimizedDrawingPoints ( pt1234 , pt234 , pt34 , end , points , distanceTolerance ) ; }
recursively subdivides a bezier curve until distanceTolerance is met.
recursively subdivides a bezier curve until distanceTolerance is met .
// calculate all the mid-points of the line segments // calculate the mid-points of the new half lines // finally subdivide the last two midpoints. if we met our distance tolerance this will be the final point we use. // try to approximate the full cubic curve by a single straight line // Continue subdivision
start
Vector2
None
firstCtrlPoint
Vector2
First ctrl point.
First ctrl point .
secondCtrlPoint
Vector2
Second ctrl point.
Second ctrl point .
end
Vector2
None
points
List<Vector2>
None
distanceTolerance
float
None