多变量Hermite样条曲线

问题描述 投票:2回答:1

我知道如何从bicubic patch(即4x4网格)中执行16 control points,例如B样条,Catmull–Rom,Besier ...

但是,我更喜欢类似于Hermite spline的2D / 3D,它由4个控制点(p00,p01,p10,p11)和4个法线(n00,n01,n10,n11)所描述。

我试图对其进行编程(首先沿u进行2x 1D插值,然后沿v进行结果插值)。

当我意识到我不知道如何使用表面法线而不是一维Hermite样条曲线中使用的导数时,我陷入了困境。

如果我只是天真地插入法线而不是导数,我将得到无意义的结果。在这里查看C ++代码(我只看了相关部分):

// basis function
template <class TYPE>  
inline void spline_hermite_basis( TYPE x, TYPE& c0, TYPE& c1, TYPE& d0, TYPE& d1 ){
    TYPE x2   = x*x;
    TYPE x3   = x*x2;
    c0        =  2*x3 - 3*x2 + 1;
    c1        = -2*x3 + 3*x2    ;
    d0        =    x3 - 2*x2 + x; 
    d1        =    x3 -   x2    ;
};

// derivative of basis functions
template <class TYPE>  
inline void dspline_hermite_basis( TYPE x, TYPE& c0, TYPE& c1, TYPE& d0, TYPE& d1 ){
    TYPE x2   = x*x;
    c0        =   6*x2 - 6*x    ;
    c1        =  -6*x2 + 6*x    ;
    d0        =   3*x2 - 4*x + 1; 
    d1        =   3*x2 - 2*x    ;
};

void cubicPatch_point( double u, double v, 
    const Vec3d& p00, const Vec3d& p01, const Vec3d& p10, const Vec3d& p11,  
    const Vec3d& n00, const Vec3d& n01, const Vec3d& n10, const Vec3d& n11, 
    Vec3d& p, Vec3d& n  
){
    double cc0,cc1,cd0,cd1;
    double dc0,dc1,dd0,dd1;
    // interpolation along u
     spline_hermite_basis<double>( u,  cc0, cc1, cd0, cd1 );
    dspline_hermite_basis<double>( u,  dc0, dc1, dd0, dd1 );
    Vec3d p0u,p1u,n0u,n1u;
    p0u.set_mul( p00, cc0 ); p0u.add_mul( p01, cc1 ); p0u.add_mul( n00, cd0 ); p0u.add_mul( n01, cd1 );   // p0u =  cc0*p00 + cc1*p01 + cd0*n00 + cd1*n01; 
    n0u.set_mul( p00, dc0 ); n0u.add_mul( p01, dc1 ); n0u.add_mul( n00, dd0 ); n0u.add_mul( n01, dd1 );   // n0u =  dc0*p00 + dc1*p01 + dd0*n00 + dd1*n01; 
    p1u.set_mul( p10, cc0 ); p1u.add_mul( p11, cc1 ); p1u.add_mul( n10, cd0 ); p1u.add_mul( n11, cd1 );   // p1u =  cc0*p10 + cc1*p11 + cd0*n10 + cd1*n11; 
    n1u.set_mul( p10, dc0 ); n1u.add_mul( p11, dc1 ); n1u.add_mul( n10, dd0 ); n1u.add_mul( n11, dd1 );   // n1u =  dc0*p10 + dc1*p11 + dd0*n10 + dd1*n11; 
    // interpolation along v
     spline_hermite_basis<double>( v,  cc0, cc1, cd0, cd1 );
    dspline_hermite_basis<double>( v,  dc0, dc1, dd0, dd1 );
    p.set_mul( p0u, cc0 );  p.add_mul( p1u, cc1 );  p.add_mul( n0u, cd0 );  p.add_mul( n1u, cd1 );        // p =  cc0*p0u + cc1*p1u + cd0*n0u + cd1*n1u; 
    n.set_mul( p0u, dc0 );  n.add_mul( p1u, dc1 );  n.add_mul( n0u, dd0 );  n.add_mul( n1u, dd1 );        // n =  dc0*p0u + dc1*p1u + dd0*n0u + dd1*n1u; 
}   

我知道如何从16个控制点(即4x4网格)(如B样条,Catmull–Rom,Besier等)进行三次三次修补。但是,我更喜欢2D / 3D类似..所描述的Hermite样条。 。

c++ 3d interpolation spline hermite
1个回答
1
投票

[您想要的是Bicubic Hermite曲面,它由4个角点以及每个角点的dS / du,dS / dv和d2S / dudv定义,其中dS / du和dS / dv是u和v方向,d2S / dudv是扭曲向量。您可以参考link1link2了解更多详细信息。

© www.soinside.com 2019 - 2024. All rights reserved.