给定距离起点的距离时,在Bézier曲线上找到一个点?

Bra*_*don 8 java bezier distance

我创造了一个4点Bézier曲线和一个距离.从起点开始,如何找到距离起点距离的点的x,y坐标?

我已经看了其他的例子,从我所知道的,他们通过将曲线分成几千个点来近似值,然后找到最近的点.这对我不起作用.对于我正在做的事情,我希望精确到只有两位小数.下面是我创建Bézier曲线的简单形式.(y值是任意的,x值总是相隔352个像素).如果重要,我正在使用Java.

path.moveTo(0, 400);
path.curveTo(352, 480, 704, 590, 1056, 550);
Run Code Online (Sandbox Code Playgroud)

因此,假设我的起点是0,400,我如何找到距离起点(沿着曲线)距离为35的点的坐标?(理想情况下,这不是处理器密集型的.这可能最终必须每秒运行200次)

Bra*_*don 6

对于碰巧找到我问题的人,我解决了自己的问题.要找到曲线的总距离,请将其分成1000个左右(仍然相当准确),找到每个点之间的距离,然后将它们全部加在一起.(你应该使用参数公式)

现在找出曲线上的百分比.= distance/totalLengthOfCurve

使用此百分比作为x和y的新t值,现在您拥有新的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;
Run Code Online (Sandbox Code Playgroud)

**现在是你计算每个点之间的距离.我建议将计算出的上述值放入数组并循环.

计算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;
Run Code Online (Sandbox Code Playgroud)

  • 对于任何也阅读评论的人来说,所描述的方法实际上并不是数学上合理的,因为沿曲线的距离沿着曲线线性增加,而`t`值以多项式增加.通过运行`t`值来构造LUT实际上更容易,对于每个x/y对,只需记录它们在`{t,x,y,d}'四倍中的距离.然后,找到d的x/y是运行列表(按"d"排序)直到d_n <= d <= d_n + 1,并为这两个记录插入x和y. (4认同)