C++ 如何使用glm_gtx_spline::catmullRom生成样条曲线?

C++ 如何使用glm_gtx_spline::catmullRom生成样条曲线?,c++,opengl,glm-math,C++,Opengl,Glm Math,我有4个点,我必须使用样条曲线与相机一起移动,如何使用glm::gtx_样条::catmullRom生成曲线 它是glm_gtx_样条函数 Catmull Rom样条曲线通常由若干段组成,每个段内插一对连续控制点。glm::catmullRom函数仅计算该曲线的一个段,该段取决于四个连续控制点(p0,p1,p2,p3)。曲线段始终从p1到p2,而点p0和p3仅影响曲线在两者之间的弯曲方式,如下所示: (哈顿福德自己的作品,CC by-SA 3.0,) 通过按顺序链接这些曲线段中的几个,可以创建

我有4个点,我必须使用样条曲线与相机一起移动,如何使用glm::gtx_样条::catmullRom生成曲线

它是glm_gtx_样条函数


Catmull Rom样条曲线通常由若干段组成,每个段内插一对连续控制点。
glm::catmullRom
函数仅计算该曲线的一个段,该段取决于四个连续控制点(
p0
p1
p2
p3
)。曲线段始终从
p1
p2
,而点
p0
p3
仅影响曲线在两者之间的弯曲方式,如下所示:


(哈顿福德自己的作品,CC by-SA 3.0,)

通过按顺序链接这些曲线段中的几个,可以创建一条Catmull Rom样条曲线,该样条曲线插值一系列(任意数量的)控制点。如果从四个连续控制点计算每个Catmull Rom曲线段,则生成的样条曲线将是连续且平滑的(C1连续)

给定n个控制点的向量
cp
,以下函数计算参数
t
处的Catmull Rom样条曲线值(其中
t
从0变为n-1):

glm::vec3 catmull_rom_样条曲线(常量std::vector&cp,浮点t)
{
//有关管制站的指数
int i0=glm::clamp(t-1,0,cp.size()-1);
int i1=glm::clamp(t,0,cp.size()-1);
int i2=glm::clamp(t+1,0,cp.size()-1);
int i3=glm::clamp(t+2,0,cp.size()-1);
//局部曲线区间上的参数
浮点局部_t=glm::fract(t);
返回glm::catmullRom(cp[i0]、cp[i1]、cp[i2]、cp[i3]、local\t);
}
在这个实现中,相关的控制点索引被限制在范围(0,n-1)内。从概念上讲,这实现了第一个和最后一个控制点的加倍,其效果是
cp
的第一个和最后一个控制点也被插值


将参数
t
在0和n-1之间变化,现在将在平滑曲线上勾勒出点,在
cp

中插入所有点,具有一些控制点的描述/图片。你只需要给它你想要的点作为曲线的基础,告诉它沿着你想要的值的曲线“有多远”。opengl中没有“曲线”这样的东西,因此您必须沿着样条线选择所需的样本数,并多次调用catmullRom来获取样本。调用次数越多,它看起来越好,但代码的速度越慢。“多远”位是最后一个参数。前4个是控制点。那么,控制点就是我想要旅行的点?我如何设置多远位呢?我是这样使用的:glm::vec3 test=glm::catmullRom(点1,点2,点3,点4,1);,它返回给我点3,这意味着我必须现在和之后移动到点4,中间控制点是定义曲线的点。它们可能不在曲线上(看我给你的维基百科链接上的图片)。假设你希望你的“曲线”是11条线段——然后你用“多远”在0,0.1,0.2,0.3,0.4,0.5,0.6…1.0处调用这11次,尽管这不会给出一条非常好的曲线,因为你希望曲线更详细,直线更少。不确定如何生成更好的“多远”
genType catmullRom (genType const &v1, genType const &v2, genType const &v3, genType const &v4, typename genType::value_type const &s)
glm::vec3 catmull_rom_spline(const std::vector<glm::vec3>& cp, float t)
{
    // indices of the relevant control points
    int i0 = glm::clamp<int>(t - 1, 0, cp.size() - 1);
    int i1 = glm::clamp<int>(t,     0, cp.size() - 1);
    int i2 = glm::clamp<int>(t + 1, 0, cp.size() - 1);
    int i3 = glm::clamp<int>(t + 2, 0, cp.size() - 1);

    // parameter on the local curve interval
    float local_t = glm::fract(t);

    return glm::catmullRom(cp[i0], cp[i1], cp[i2], cp[i3], local_t);
}