2

我有一条由多个点组成的路径 - 即 0,0 0,50 50,50 70,20

如果我只是在屏幕上画这条线,它看起来很刺眼,因为它在每个点的连接处都设置了一个锐角。

因此,我想知道贝塞尔曲线算法/方法会是什么样子,我可以称之为自动将锐角更改为“紧”曲线?

我不希望曲线太大或通常影响主路径的下降,只需软化连接即可。如果您看一下下面的内容,这里是我整理的一个快速示例。左边的线是我现在的线,中间的线是我想要的线。

右边的图像代表我认为我需要算法做的事情。本质上,我在距离连接 10% 的点处为构成连接的每个弧添加了一个附加点,然后我移除连接点并调整手柄,使它们位于点所在的位置(不在图中它们稍微分开,这只是为了让你可以看到)。这是我需要能够做到的。

替代文字

4

2 回答 2

3

呃....只需将BezierSegment添加到您的 PathSegmentCollection。

于 2010-09-03T02:50:47.680 回答
1

因此,您需要为每个“角”点确定 2 个附加点。“拐角”点是路径上的任何内部点。

这是一个开始:

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;
}
于 2010-09-03T15:36:11.350 回答