三次贝塞尔:前导系数为零怎么办?
Cubic Bézier: What to do when leading coefficient is zero?
我使用相当标准的方法从三次贝塞尔曲线的控制点中检索一元多项式系数:
std::array<double, 3> getBezierCubicCoefficients( const std::array<double, 4>& bezier )
{
const auto d = 1.0 / ( bezier[3] - 3*bezier[2] + 3*bezier[1] - bezier[0] );
return { ( 3*bezier[2] - 6*bezier[1] + 3*bezier[0] ) * d,
( 3*bezier[1] - 3*bezier[0] ) * d,
bezier[0] * d };
}
这在 99% 的时间里工作正常,但正如您可能已经猜到的那样,在某些坐标下失败导致 d
的除数计算为零 - 导致 d
计算为 Inf
.
我的问题是:这种情况下怎么办?
我真的得到了伪装的二次曲线,我应该改为进行降阶吗?我是否应该捏造数字以使 d
非常大,但不会导致 Inf
? (我真的希望这不是答案)。
您可能已经知道,单项系数 c
可以通过与以下矩阵相乘从贝塞尔系数计算得出:
/ 1 -3 3 -1 \
| 3 -6 3 |
(c0 c1 c2 c3) = (b0 b1 b2 b3) | 3 -3 |
\ 0 1 /
如果结果 c3 = -b0 + 3b1 - 3b2 + b3
为零,那么您将得到一个二次多项式(最多)。在退化的情况下,其他系数也可以产生 0
。在极端情况下,您最终会得到一个常数。
我使用相当标准的方法从三次贝塞尔曲线的控制点中检索一元多项式系数:
std::array<double, 3> getBezierCubicCoefficients( const std::array<double, 4>& bezier )
{
const auto d = 1.0 / ( bezier[3] - 3*bezier[2] + 3*bezier[1] - bezier[0] );
return { ( 3*bezier[2] - 6*bezier[1] + 3*bezier[0] ) * d,
( 3*bezier[1] - 3*bezier[0] ) * d,
bezier[0] * d };
}
这在 99% 的时间里工作正常,但正如您可能已经猜到的那样,在某些坐标下失败导致 d
的除数计算为零 - 导致 d
计算为 Inf
.
我的问题是:这种情况下怎么办?
我真的得到了伪装的二次曲线,我应该改为进行降阶吗?我是否应该捏造数字以使 d
非常大,但不会导致 Inf
? (我真的希望这不是答案)。
您可能已经知道,单项系数 c
可以通过与以下矩阵相乘从贝塞尔系数计算得出:
/ 1 -3 3 -1 \
| 3 -6 3 |
(c0 c1 c2 c3) = (b0 b1 b2 b3) | 3 -3 |
\ 0 1 /
如果结果 c3 = -b0 + 3b1 - 3b2 + b3
为零,那么您将得到一个二次多项式(最多)。在退化的情况下,其他系数也可以产生 0
。在极端情况下,您最终会得到一个常数。