计算三次贝塞尔曲线java

时间:2019-03-12 21:51:28

标签: java graphics linear

我试图计算由点p0,p1,p2,p3和t定义的三次贝塞尔曲线的切线。

我知道这应该是简单的计算,并且切线应该只是三次贝塞尔曲线方程的导数。我尝试以与计算曲线点相同的方式执行此操作:将每个p0-p3的x值分别传递给三次方Bezier方程,然后对y点进行相同处理,然后将结果用于曲线上下一个点的x,y坐标(下一个是t处的点)

问题是,尽管上述方程式起作用并且我绘制了准确的贝塞尔曲线,但当我尝试对点t处的切向量进行同样的处理时,它们都大为偏离(特别是过高(-y值) )和左侧)。

My graph

另一个困扰我的问题是,我知道在t = 0.0时曲线的切向量应从p0到p1,但是将其应用于导数时,它最终被简化了: -3 * p0 + 3 * p1除非p1和p0相同,否则永远不会是p1?

我觉得我在这里错过了一个额外的步骤。

我还查看了Find the tangent of a point on a cubic bezier curve不适用于我的地方。

我还应该提到我正在用java graphics2d canvas进行所有操作,因此原点在左上角,y轴的正方向为“向下”,y轴的负方向为“向上”,x轴为正常- -我不确定这是否有问题。

贝塞尔曲线计算代码(仅x或y)

private static double getPoint(double a0, double a1, double a2, double a3, double detail) {
    return Math.pow(1 - detail, 3) * a0 
     + 3 * Math.pow(1 - detail, 2) * detail * a1
     + 3 * (1 - detail) * Math.pow(detail, 2) * a2
     + Math.pow(detail, 3) * a3;
}

正切计算代码如下。

double tan = -3 * p0 * (Math.pow(1-t,2)) +
              p1 * (3*(Math.pow(1-t,2)) - 6*(1-t)*t) +
              p2*(6 * (1-t) * t) - (3 * Math.pow(t,2)) +
              3 * p3 * Math.pow(t, 2);`

在这里,我将传递p0-p3的x值,然后传递p0-p3的y值,并从这两个值中获取切线的(end?)坐标。

有什么明显的失踪吗?

1 个答案:

答案 0 :(得分:0)

如何渲染切线?它们应呈现为从<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>Nav</title> </head> <body> <nav class="nav"> <ul> <li><a href="#">Section 1</a></li> <li><a href="#">Section 2 ▾</a> <ul> <li><a href="#">Section 2.1</a></li> <li><a href="#">Section 2.2</a></li> <li><a href="#">Section 2.3</a></li> </ul> </li> <li><a href="#" class="active">Section 3 ▾</a> <ul> <li><a href="#" class="active">Section 3.1</a></li> <li><a href="#">Section 3.2 ▸</a> <ul> <li><a href="#">Section 3.2.1</a></li> <li><a href="#">Section 3.2.2</a></li> <li><a href="#">Section 3.2.3 ▸</a> <ul> <li><a href="#">Section 3.2.3.1</a></li> <li><a href="#">Section 3.2.3.2</a></li> </ul> </li> </ul> </li> <li><a href="#">Section 3.3</a></li> </ul> </li> </ul> </div> </body> </html>position(t)结束的线,其中position(t)+size*tangent(t)是将切线切成可见/可用长度的常量比例。

我敢打赌,您忘记了最后一个端点中的size(即使我之前几次也犯过新秀错误)。如果没有任何效果,您也可以使用position(t)+作为切线。