views:

92

answers:

2

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 is 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.

alt text

+2  A: 

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

Randolpho
Thanks... but I think you have missed the point of the question... I need an algorithm that will work out how to do this. I knew in advance that I needed a BezierSegment but its the calculation and the algorithm.
vdh_ant
So what do you want to do? Calculate the anchor points? Or draw the spline? Be careful, there is some pretty serious math involved in drawing splines ;)
CommanderZ
Well I guess its two parts... one is calculating the splines based on a list of points that are feed in and the second is tacking the result and drawing the line. Note, if there is a component that will do this for me I am more than happy for that, just let me know but I haven't been able to find one yet.
vdh_ant
Just having a little bit more of a look and I think what I want is called "canonical splines"??? See http://floris.briolas.nl/floris/?p=144 - but the problem with this example is you can see how the "canonical splines" bend the main line... in my example its only the points that are rounded... Any ideas?
vdh_ant
+1  A: 

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;
}
sixlettervariables
Ok this is great... I think its right along the lines of what I am after. With this, I can remove the corner point if I want, but I would I add in the "Splines" (I think thats the correct terminology) so that the anchor of the nodes on either side of the corner point is set to the location of the corner point. See the right most image in the example I provided to see the end result of how the Splines are setup.
vdh_ant