贝塞尔曲线..添加法线(在3D中)



我有一个bezier曲线类。曲线上的每个点都是这样定义的:

struct bpoint
{
vector3D position;
vector3D controlpoint_in;
vector3d controlpoint_out;
};

要检索曲线样条曲线上的一个点(曲线可以有无限个点(,我使用以下函数:

vector3d GetSplinePoint(float thePos)
{
float aPos=thePos-floorf(thePos);
int aIPos=(int)floorf(thePos);
bpoint& aP1=pointList[aIPos];
bpoint& aP2=pointList[min(aIPos+1,pointList.size())];
vector3D aResult;
vector3D aAB, aBC, aCD, aABBC, aBCCD;
Lerp(aAB,aP1.mPos,aP1.mOut,aPos);
Lerp(aBC,aP1.mOut,aP2.mIn,aPos);
Lerp(aCD,aP2.mIn,aP2.mPos,aPos);
Lerp(aABBC,aAB,aBC,aPos);
Lerp(aBCCD,aBC,aCD,aPos);
Lerp(aResult,aABBC,aBCCD,aPos);
return aResult;
}

效果很好,但现在我想为每个点添加法线,这样我就可以做一些更花哨的事情(旋转等(。像这样:

struct bpoint
{
vector3D position;
vector3D controlpoint_in;
vector3d controlpoint_out;
vector3d normal;
};

我在尝试编写GetSplineNormal(float-Pos(函数时完全失败了。我甚至不知道从哪里开始——我以为我可以在点之间插值,但我不知道如何考虑控制点。

我怎样才能做到这一点?

好的,从数学角度来说,有一些事情需要考虑。

首先,曲线有一个特定的形状,因此在曲线的每个点都有一个且只有一个平面垂直于曲线的当前方向。法线必须是该平面的一部分。

因此,你的曲线是由Pos参数化的,为了简化我的数学符号,我将写为t:x(t(,y(t(和z(t(。位置t处的垂直平面由以下方程给出:

d_t x(t(*(x-x(t

其中d_tx(t(是x(t(、y(t(的d_ty(t。

对于法向量的方向(即法线在该垂直平面中面向的方向(,可以在两个控制点之间进行插值。只要注意,插值角度可能很棘手,因为你必须考虑方向。角度坐标的线性插值是一种选择,但也可以直接对法向量进行插值,然后使用最小二乘法在垂直平面上重新投影。这真的取决于你想用法线做什么。

最后,请记住,这个垂直平面也存在于控制点处,因此您可能必须约束用户给定的法线(通过使用最小二乘法重新投影(。

相关内容

  • 没有找到相关文章

最新更新