开发者

Bezier curves algorithm - maybe Canonical Splines?

开发者 https://www.devze.com 2023-01-14 01:38 出处:网络
I\'ve got a path that is made up of multiple points - i.e. 0,00,5050,5070,20 If I just draw this line on the screen it looks quite harsh as it puts a sharp angle at the joining of each point.

I've got a path that is made up of multiple points - i.e. 0,0 0,50 50,50 70,20

If I just draw this line on the screen it looks quite harsh as it puts a sharp angle at the joining of each point.

Hence I was wondering what the bezier curves algorithm/method would look like which I could call that automatically change the sharp angles to "tight" curves?

I wouldn't want the curve to be too big or generally effect the fall of main path, just soften the join out. If you have a look at the below here 开发者_StackOverflowis a quick sample I have put together. The line on the left is what I have now, the one in the middle is the line I want.

The image on the right represents what I think I need the algorithm to do. Essentially, I add an additional point to each arc that makes up the join at a point which 10% away from the join, then I remove the join point and adjust the handles so that they are where the point was (not in the diagram they are slightly apart, this is just so that you can see). This is what I need to be able to do.

Bezier curves algorithm - maybe Canonical Splines?


Er.... just add a BezierSegment to your PathSegmentCollection.


So you need to identify 2 additional points per "corner" point. A "corner" point being any interior point along the path.

Here is a start:

public List<Point> AddControlPoints(List<Point> path)
{
    // arbitrary minimum length to use to make a corner
    double segmentLengthThreshold = 10.0;
    double cornerDistance = 2.0;

    if (path.Count < 3) return path.ToList(); // arbitrarily a copy

    var newPath = new List<Point>();
    newPath.Add(path[0]);
    for (int ii = 1; ii < path.Count - 1; ii += 2)
    {
        // walk each "corner" point and do line interpolation for the point
        double m = (path[ii].Y - path[ii-1].Y) / (path[ii].X - path[ii-1].X);
        double b = (path[ii].Y - m * path[ii].X);

        // above we setup the equation to move along the line
        // find the new X value and move along it
        double xi = path[ii].X - cornerDistance/m;
        newPath.Add(new Point(xi, m * xi + b));
        newPath.Add(path[ii]);

        // repeat for the next side
        m = (path[ii+1].Y - path[ii].Y) / (path[ii+1].X - path[ii].X);
        b = (path[ii].Y - m * path[ii].X);

        xi = path[ii].X + cornerDistance/m;
        newPath.Add(new Point(xi, m * xi + b));

        // this will likely fail in many ways, 0 slopes etc
        // but throwing the equations some test values shows it makes
        // decent control points. If you'd like them to be length based
        // just find the distance of the two points and multiply by a
        // factor
    }

    return newPath;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消