2017-07-18 45 views
2

我想用Hermite样条插值4点之间。不过,我的样条似乎总是从第二点开始,只插入到第三点。我已经尝试了几个不同的计算,并得到相同的结果。Hermite插值

任何人都可以给我这方面的见解吗?这是我的代码。

public ControlPoint Get(float t) 
{ 
    //speed multiplyer 
    //t = t * 10; 

    return new ControlPoint(
     new Vector3(Hermite(points[0].pos.x, points[1].pos.x, points[2].pos.x, points[3].pos.x, t) 
     , Hermite(points[0].pos.y, points[1].pos.y, points[2].pos.y, points[3].pos.y, t) 
     , Hermite(points[0].pos.z, points[1].pos.z, points[2].pos.z, points[3].pos.z, t) 
     ), 
     new Quaternion(Hermite(points[0].rot.x, points[1].rot.x, points[2].rot.x, points[3].rot.x, t) 
     , Hermite(points[0].rot.y, points[1].rot.y, points[2].rot.y, points[3].rot.y, t) 
     , Hermite(points[0].rot.z, points[1].rot.z, points[2].rot.z, points[3].rot.z, t) 
     , Hermite(points[0].rot.w, points[1].rot.w, points[2].rot.w, points[3].rot.w, t) 
     ) 
     ); 
} 

float Hermite(
    float y0, float y1, 
    float y2, float y3, 
    float mu, 
    float tension = 0, 
    float bias = 0) 
{ 
    float m0, m1, mu2, mu3; 
    float a0, a1, a2, a3; 

    mu2 = mu * mu; 
    mu3 = mu2 * mu; 
    m0 = (y1 - y0) * (1 + bias) * (1 - tension)/2; 
    m0 += (y2 - y1) * (1 - bias) * (1 - tension)/2; 
    m1 = (y2 - y1) * (1 + bias) * (1 - tension)/2; 
    m1 += (y3 - y2) * (1 - bias) * (1 - tension)/2; 
    a0 = 2 * mu3 - 3 * mu2 + 1; 
    a1 = mu3 - 2 * mu2 + mu; 
    a2 = mu3 - mu2; 
    a3 = -2 * mu3 + 3 * mu2; 

    return (a0 * y1 + a1 * m0 + a2 * m1 + a3 * y2); 
} 

回答

0

我不是专家埃尔米特样条由任何想象的延伸,但是从我所看到的是,预期的行为将是第二和第三点之间进行插值。在我看来,你只需要在每个坐标中对你的Get函数进行硬编码,所以当Hermite样条曲线是一个函数时,只有一次插值才有意义。把第二点和第三点想象成你想插入的两点,第一点和第四点只是帮助创建更好的曲线。

由于它看起来总共只有四个点,要在第一个点和第二个点以及第三个点和第四个点之间进行插值,请尝试重复第一个坐标和最后一个坐标。

//Interpolate between 1st and 2nd points' x coord Hermite(points[0].pos.x, points[0].pos.x, points[1].pos.x, points[2].pos.x);

//Interpolate between 3rd and 4th points' x coord Hermite(points[2].pos.x, points[3].pos.x, points[4].pos.x, points[4].pos.x);

向该第一和第二点之间points[0]内插被重复两次,因为没有points[-1]。对于第三点和第四点之间的插值,重复points[4],因为没有points[5]

重申,除非您只需要单个插值,否则不要在坐标中进行硬编码。你必须修改你的Get函数,并调用它几次来调整你想要的行为。看看Snea如何在他的DrawGraph函数中实现Hermite样条曲线,它帮助我更好地理解Hermite样条曲线的行为:Cubic Hermite Spline behaving strangely