Javascript 给定的三次贝塞尔曲线未返回正确的Y值(t、p0、p1、p2、p3)
我的目标是用JavaScript编写一个动画,它执行一个ease-in-out风格的bezier曲线动画 (如在) 我提出了以下脚本来计算给定“x”值(时间)的y值: 使用以下公式中的显式公式: 演示- 但是,print语句显示Y值在上升之前先下降,此时它应该只上升:Javascript 给定的三次贝塞尔曲线未返回正确的Y值(t、p0、p1、p2、p3),javascript,css,animation,cubic-bezier,Javascript,Css,Animation,Cubic Bezier,我的目标是用JavaScript编写一个动画,它执行一个ease-in-out风格的bezier曲线动画 (如在) 我提出了以下脚本来计算给定“x”值(时间)的y值: 使用以下公式中的显式公式: 演示- 但是,print语句显示Y值在上升之前先下降,此时它应该只上升: 0.42 0.3228427793606603 0.3119941308275725 0.3025864871426283 0.29458762995005683 0.2879653408940873 0.28268740161
0.42
0.3228427793606603
0.3119941308275725
0.3025864871426283
0.29458762995005683
0.2879653408940873
0.28268740161894895
0.27872159376887096
0.27603569898808256
0.27459749892081287
0.2743747752112911
0.2753353095037466
0.27744688344240837
0.28067727867150566
0.2849942768352678
0.29675920854370297
0.3041427053768346
0.3124839317215477
0.3217506690862967
0.33191069937460593
0.34293180410763435
0.35478176492961133
我确实设法找到了其他人的代码,似乎可以使用,以下是输出:
0
0.009480343767040133
0.0246451904411195
0.03199616010201068
0.040680303103589804
0.05080871722437687
0.062492500242891866
0.07584274993765482
0.0909705640871857
0.10798704047000454
0.12700327686463134
0.14813037104958607
0.17147942080338874
0.19716152390455938
0.225287778131618
0.25596928126308455
0.28931713107747903
0.3254424253533215
0.36445626186913194
0.4064697384034303
0.4515939527347367
0.499940002641571
演示-
两个演示使用相同的输入:p0=.42,p1=0,p2=.58,p3=1
我不知道为什么我的尝试失败了,我找到的代码也能工作。我是否执行了错误的公式?我选错公式了吗?还有什么吗?我想你的公式可能有错误,运算符优先。我会在适当的地方尝试使用求幂函数,这会使调试更容易
Math.pow(base, exponent)
因此,您的错误既不是传递单个值,也不是传递幂函数。错误在于你假设x=t 我提出了以下脚本来计算给定“x”值(时间)的y值: 如果x=t,那么您得到的是一条显式贝塞尔曲线,而不是一条参数化贝塞尔曲线。明确表示y是x的函数(即y=f(x))。与参数方程相反,其中x和y都是t的函数(即x=f(t)和y=f(t)) 要测试这种情况是否属实,可以将x值设置为[0,1/3,2/3,1]。均匀分布的x值确保x=t,并将为您提供一条明确的贝塞尔曲线。您可以通过将地址栏中的x值设置为0.333和0.666来实现这一点。但一旦将控制点向左或向右移动,结果将再次不同
为了达到同样的效果,它需要更多的参与。你们必须在给定的x上求解t,然后从t计算y。求解t有点复杂,但可以用牛顿-拉斐逊法近似。这个链接在解释如何实现它方面做得更好:派对迟到了,但是:你的评论“我认为我实际上犯了一个很大的错误——p应该是点值……应该是(x,y),我只提供一个数字”是正确的 贝塞尔曲线是一种参数函数,其中x和y(或3D中的x、y和z)都是t的函数。您只计算了曲线的一半,因此需要修改
CalculateBezierPoint
函数以返回x/y坐标,而不仅仅是y坐标:
calculateBezierPoint(t, xvalues, yvalues) {
return new Point(
x = calculateBezierDim(t, x1, x2, x3, x4),
y = calculateBezierDim(t, y1, y2, y3,y4)
);
}
calculateBezierDim(t, vals) {
a=vals[0], b=vals[1], c=vals[2], d=vals[3];
mt = 1-t;
t2 = t*t;
mt2 = mt*mt;
return a * mt*mt2 + 3 * b * mt2 * t + 3 * c * mt * t2 + d * t2 * t;
}
(当然适合您的编程语言和数据类型)
然后可以绘制该x/y坐标
step = some small value
S = calculateBezierPoint(0, xvals, yvals)
for(t=step; t<1+step; t+=step) {
E = calculateBezierPoint(t, xvals, yvals)
drawLine(S.x, S.y, E.x, E.y)
S = E
}
step=某个小值
S=calculateBezierPoint(0,xvals,yvals)
对于(t=step;tYeah,这是很有可能的..只是尝试在这里使用Math.pow来实现它:得到了与我第一次尝试buggy时非常相似(但不完全相同)的输出。我想我实际上犯了一个很大的错误--P应该是点值..哪个应该有(x,y),而我只提供了一个数字?
step = some small value
S = calculateBezierPoint(0, xvals, yvals)
for(t=step; t<1+step; t+=step) {
E = calculateBezierPoint(t, xvals, yvals)
drawLine(S.x, S.y, E.x, E.y)
S = E
}