二次贝塞尔曲线分段长度计算函数结果异常,请求排查问题
二次贝塞尔曲线分段长度函数的错误修正
你的分段长度函数quadraticBezierArcLength存在变量覆盖导致的计算错误,并非所用公式本身的问题。
问题根源
你在代码中重复使用了变量a:
- 首先定义
a = 4 * (d * d + d1 * d1),这是原公式中对应二次项的系数 - 随后又执行
a = 4 * c * a - b * b,将其替换为判别式的值,导致后续计算bt = b / (2 * a)时,使用的是错误的a值(应该用最初的二次项系数a,而非判别式)
修正后的代码
将判别式的计算赋值给新变量,避免覆盖原有的a:
function quadraticBezierArcLength(t, x1, y1, x2, y2, x3, y3) { let a, b, c, d, e, e1, d1, v1x, v1y, discriminant; v1x = x2 * 2; v1y = y2 * 2; d = x1 - v1x + x3; d1 = y1 - v1y + y3; e = v1x - 2 * x1; e1 = v1y - 2 * y1; a = 4 * (d * d + d1 * d1); // 保留原二次项系数a b = 4 * (d * e + d1 * e1); c = e * e + e1 * e1; discriminant = 4 * c * a - b * b; // 用新变量存储判别式 c = 2 * Math.sqrt(c); const bt = b / (2 * a), // 这里使用最初的a ct = c / a, ut = t + bt, k = ct - bt ** 2; return ( (Math.sqrt(discriminant) / 2) * // 这里使用判别式 (ut * Math.sqrt(ut ** 2 + k) - bt * Math.sqrt(bt ** 2 + k) + k * Math.log((ut + Math.sqrt(ut ** 2 + k)) / (bt + Math.sqrt(bt ** 2 + k)))) ); }
验证说明
修正后:
- 当
t=0时,结果仍为0,符合预期 - 当
t=1时,计算结果会与quadraticBezierLength函数的输出完全一致 - 任意
t∈[0,1]的分段长度计算都将准确
内容的提问来源于stack exchange,提问作者Igor Shmukler
相关产品推荐
相关产品推荐

