【问题标题】:Bezier curves algorithm - maybe Canonical Splines?贝塞尔曲线算法 - 也许是典型样条?
【发布时间】:2011-04-07 15:50:38
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: .net wpf algorithm path-finding bezier


    【解决方案1】:

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

    【讨论】:

    • 谢谢......但我认为你错过了问题的重点......我需要一个算法来解决如何做到这一点。我事先知道我需要一个 BezierSegment 但它的计算和算法。
    • 那你想做什么?计算锚点?还是画样条?小心,绘制样条曲线涉及一些非常严肃的数学;)
    • 嗯,我猜它有两个部分......一个是根据输入的点列表计算样条曲线,第二个是跟踪结果并绘制线。请注意,如果有一个组件可以为我做到这一点,我会非常高兴,请告诉我,但我还没有找到。
    • 只是多看一点,我想我想要的是所谓的“规范样条曲线”???见floris.briolas.nl/floris/?p=144 - 但这个例子的问题是你可以看到“规范样条”如何弯曲主线......在我的例子中,它只有被舍入的点......有什么想法吗?
    【解决方案2】:

    因此,您需要为每个“角”点确定 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;
    }
    

    【讨论】:

    • 好的,这很棒...我认为它与我所追求的一致。有了这个,我可以根据需要删除角点,但我会添加“样条线”(我认为这是正确的术语),以便将角点两侧节点的锚点设置为位置的角点。请参阅我提供的示例中最右侧的图像,以了解如何设置样条线的最终结果。
    猜你喜欢
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-03
    相关资源
    最近更新 更多