我试图计算由点p0,p1,p2,p3和t定义的三次贝塞尔曲线的正切。
我知道这应该是一个简单的计算,切线应该只是三次贝塞尔曲线方程的导数。我试图以与计算曲线点相同的方式进行此操作:通过将每个p0-p3的x值分别传递给三次Bezier方程,然后对y点进行相同的操作,然后使用结果曲线上下一个点的x,y坐标(下一个是t点)
问题在于,虽然上面的等式有效并且我得到了精确的贝塞尔曲线,当我尝试对点t处的切向量做同样的事情时,它们都是大量关闭的(特别是太高(-y值)并且左边)。
困扰我的另一个问题是我知道在t = 0.0时曲线的切向量应该是从p0到p1但是当将它应用于导数时它最终会被(简化):-3 * p0 + 3 * p1
除非p1和p1,否则它将永远不会是p1 p0是一样的吗?
我觉得我在这里错过了一个额外的步骤。
我也看过Find the tangent of a point on a cubic bezier curve哪个不适合我。
我还应该提到我在Java graphics2d画布中都这样做,因此原点在左上方,正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?)的坐标。
有什么明显我不知道的吗?
你如何渲染切线?它们应该呈现为从position(t)
开始并在position(t)+size*tangent(t)
结束的一条线,其中size
是一个常量缩放可见/可用长度的切线......
我的赌注是你在最后一个终点忘记了position(t)+
(即使我之前做过几次常见的新手错误)。如果没有任何作用,你也可以使用postion(t+dt)-position(t)
作为切线。