我需要找到曲面的视界的2个点。
我有:
我需要计算:
答案 0 :(得分:4)
首先,您必须将3D贝塞尔曲线转换为2D。如果我没记错,就像投影3D点进行渲染一样投影曲线就足够了。
之后你必须找到曲线的极值。
将贝塞尔曲线从贝塞尔曲线表示转换为格式
的多元曲线 x(t) = a*t^3 + b*t^2 + c*t + d
y(t) = e*t^3 + f*t^2 + g*t + g
Here t is your interpolation variable that goes from 0 to 1.
a to d are the coefficients for the curve along the x-axis
e to g are the coefficients for the curve along the y-axis.
现在你构建了曲线的第一个推导(很容易,因为它是一个polynomail)。 这将给你一个二次方程。解决这些根源并丢弃0..1范围之外的所有根。再次找到根是很容易的,因为它只是一个二次多项式。
你是如何拥有一堆根源的。将所有这些插回原始的贝塞尔曲线,评估它们的位置,然后得到一堆积分。极端 - 如果存在 - 将在这些点之中。
现在你所要做的就是搜索具有最高(或最低 - 不知道你的坐标系看起来如何)y坐标的那个。
请注意,您可能根本没有得到极值。如果您的bezier例如是直线,则会发生这种情况。在这些情况下,您可能还希望在极值搜索中包含第一个和最后一个贝塞尔控制点。
编辑:
你已经问过如何将bezier变成多项式。那么,你从正常的贝塞尔曲线方程开始:
x(t) = x0 * (1-t)³ + 3*x1*(1-t)²*t + 3*x2*(1-t)*t² +x3*t³
(x0到x3是曲线的四个控制点的x值)。
然后,你逐个将所有术语相乘,并用t的幂来对它们进行排序。不幸的是我没有在我正在写的计算机上运行我的数学包,而且我懒得在纸上做:-)所以如果有人运行了mathlab,你能不能编辑这个答案并添加扩展版本
无论如何,既然你对多项式并不感兴趣,只是它的衍生物更容易。您可以直接获得系数(此处仅显示x):
A = 3.0f*(x[1] - x[0]);
B = 6.0f*(x[2] - 2.0f*x[1] + x[0]);
C = 3.0f*(x[3] - 3.0f*x[2] + 3.0f *x[1] - x[0]);
使用这三个值(A,B,C),第一个导数的多项式如下所示:
x(t) = A*t^2 + B*t + C
现在将A,B和C插入到二次多项式的根求解器中,就完成了。作为参考,我使用下面的求解器C代码:
int GetQuadraticRoots (float A, float B, float C, float *roots)
{
if ((C < -FLT_EPSILON) || (C > FLT_EPSILON))
{
float d,p;
// it is a cubic:
p = B*B - 4.0f * C*A;
d = 0.5f / C;
if (p>=0)
{
p = (float) sqrt(p);
if ((p < -FLT_EPSILON) || (p > FLT_EPSILON))
{
// two single roots:
roots[0] = (-B + p)*d;
roots[1] = (-B - p)*d;
return 2;
}
// one double root:
roots[0] = -B*d;
return 1;
} else {
// no roots:
return 0;
}
}
// it is linear:
if ((B < -FLT_EPSILON) || (B > FLT_EPSILON))
{
// one single root:
roots[0] = -A/B;
return 1;
}
// it is constant, so .. no roots.
return 0;
}