摘要:我正在尝试使用牛顿方法找到三次多项式的特定根,但是它收敛于错误的值。
详细信息:我想在控制点为[[P 0 – P 3的三次贝塞尔曲线上找到特定x的y值。控制三次贝塞尔曲线的参数方程为:
s 3 P 0
+ 3s 2 tP 1 + 3st 2 P 2 + t 3 P 3…其中s = 1-t。
将其扩展为x
组件,对术语进行分组,并设置为等于所需值:x =(-t 3 + 3t 2-3t +1)x 0
+(3t 3-6t 2 + 3t) x 1 +(3t 2-3t 3)x 2 + t 3 x 3x = -t 3 x 0
+ 3t 2 x 0-3tx 0 + x 0 + 3t 3 x 1-6t 2 x 1 + 3tx 1 + 3t 2 x 2-3t 3 x 2 + t 3 x 3x =(-x 0
+ 3x 1 -3x 2 + x 3)t 3 + 3(x 0] >-2x 1 + x 2)t 2 + 3(-x 0 + x 1)t + x 0 = x 查找三次多项式的根at 3
+ bt 2 + ct + d = 0a = -x0
+ 3x 1 -3x 2 + x 3b = 3(x 0-2x 1 + x 2)c = 3(-x 0 + x 1)d = x 0-x时间开始实用编程。我已设置此代码:function bezierXIntersect(x0, y0, x1, y1, x2, y2, x2, y3, x) {
const a = -x0 + 3*x1 -3*x2 + x3,
b = 3*(x0 - 2*x1 + x2),
c = 3*(-x0 + x1),
d = x0 - x
const t = newtonCubicSolve(a, b, c, d),
s = 1-t
return s**3 * y0 + 3 * s**2 * t * y1 + 3 * s * t**2 * y2 + t**3 * y3
}
function newtonCubicSolve(a, b, c, d) {
let cubic = t => a*t**3 + b*t**2 + c*t + d
let deriv = t => 3*a*t**2 + 2*b*t + c
return newton(0.5, cubic, deriv)
}
function newton(t, f, f1, n) {
const t2 = t - f(t)/f1(t)
return n>6 ? t2 : newton(t2, f, f1, (n||0)+1)
}
我将使用四个已知点的曲线对此进行测试:
const x0=352, y0=599,
x1=381, y1=626,
x2=489, y2=364,
x3=536, y3=359
let y = bezierXIntersect(x0, y0, x1, y1, x2, y2, x3, y3, 400)
[和P 2的x值介于P 0和 P 3,这保证了[[t在0–1之间只有一个解决方案。摘要:我正在尝试使用牛顿方法找到三次多项式的特定根,但是它收敛于错误的值。详细信息:我想在...上找到特定x的y值...= 400
处的那些点的正确值(由Wolfram-Alpha并在SVG中绘制该点确定)为t =
=0.32244
和y =553.281
。但是,我上面的牛顿方法返回t0.2807
,因此y =
= [0,1]范围内的单个立方根?565.487
。怎么了?如果我将牛顿和硬编码t =0.32244
跳过到函数中,则会返回正确的y值。如果我将日志语句放入迭代调用中,它并不是不稳定的,它可以平滑地收敛到0.2807
。而且,除了解决上面我做错的事情之外,还有没有更好的方法来解决必须存在于t哦,如果有帮助,可以保证
P1