当给定从起点开始的距离时,如何在Bézier曲线上找到一个点?

8
我创建了一个4点贝塞尔曲线和一个距离。从起始点开始,我怎样才能找到离起始点该距离的x,y坐标?我查看了其他的例子,从中我可以得知,它们通过将曲线分成几千个点来近似值,然后找到最近的点。这对我的操作不起作用。为了我的需求,我只需要精确到小数点后两位。下面是我所创建的贝塞尔曲线的简单形式。(y值是任意的,x值总是相隔352像素)。如果需要,我正在使用Java进行操作。
path.moveTo(0, 400);
path.curveTo(352, 480, 704, 590, 1056, 550);

假设我的起点是0,400,如何找到一个点的坐标,这个点与起点沿着曲线距离为35?(最好不要太消耗处理器资源。这个过程可能需要每秒运行200次)
2个回答

6
对于任何发现我的问题的人,我解决了自己的问题。要找到曲线的总距离,请将其分成1000个小段(仍然相当准确),找到每个点之间的距离,然后将它们加在一起。(您应该使用参数方程)
现在找到沿着曲线的百分比。= 距离/曲线的总长度
使用此百分比作为您的新t值用于x和y,现在您有了新的x和y位置。
重要提示:这是一个奇怪的情况,但请确保如果您的t值大于1,则使用绝对值。当您将其立方时,该值将为负... =糟糕的事情会发生。
下面显示了丑陋但相关的代码。
将曲线分成1000个部分
    for (double t = 0.00; t < 1.001; t= t + .001) {
         double xValue = Math.pow((1-t), 3) * point1x + 3 * Math.pow((1-t), 2) * t * point2x + 3 * (1-t) * Math.pow(t, 2) * point3x + Math.pow(t, 3) * point4x;
         double yValue = Math.pow((1-t), 3) * point1y + 3 * Math.pow((1-t), 2) * t * point2y + 3 * (1-t) * Math.pow(t, 2) * point3y + Math.pow(t, 3) * point4y;

现在需要计算每个点之间的距离。我建议将上述计算出的值放入一个数组中并进行循环。

计算x和y位置

    xPos = Math.abs(Math.pow((1 - percenttraveled), 3)) * point1x + 3 * Math.pow((1 - percenttraveled), 2) * percenttraveled * point2x + 3 * Math.abs((1 - percenttraveled)) * Math.pow(percenttraveled, 2) * point3x + Math.abs(Math.pow(percenttraveled, 3)) * point4x;
    yPos = Math.abs(Math.pow((1 - percenttraveled), 3)) * point1y + 3 * Math.pow((1 - percenttraveled), 2) * percenttraveled * point2y + 3 * Math.abs((1 - percenttraveled)) * Math.pow(percenttraveled, 2) * point3y + Math.abs(Math.pow(percenttraveled, 3)) * point4y;

4
如果有其他人阅读评论,请注意,所描述的方法实际上在数学上并不正确,因为沿着曲线的距离沿着曲线线性增加,而“t”值呈多项式增长。更容易的方法是通过运行“t”值来构建LUT,并且对于找到的每个x/y对,只需记录它们在“{t,x,y,d}”四元组中的距离。然后,要找到d的x/y值,只需遍历(按“d”排序)列表,直到d_n <= d <= d_n+1,并对这两条记录进行插值即可。 - Mike 'Pomax' Kamermans
使用德卡斯特里奥算法,可以用30-40个点获得非常好的贝塞尔曲线估计,这种方法非常易于理解和实现。1000个点太多了。 - BlueRaja - Danny Pflughoeft

1
javagraphics库提供了MeasuredShape类(https://javagraphics.java.net/doc/com/bric/geom/MeasuredShape.html),该类提供了getPoint方法来执行此操作。它还有一些非常方便的获取子路径和切线角度的方法。据我所知,它们正在“正确地”实现路径逻辑,而不是分解路径。我已经在需要这种几何计算的项目中使用了该库的这部分内容,它似乎完美地工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接