Simbody  3.7
SimTK::Geo::CubicHermiteCurve_< P > Class Template Reference

A primitive useful for computations involving a single cubic Hermite curve segment in algebraic or geometric (Hermite) form. More...

Public Member Functions

 CubicHermiteCurve_ ()
 Construct an uninitialized curve; coefficients will be garbage. More...
 
 CubicHermiteCurve_ (const Vec< 4, Vec3P > &A)
 Construct a cubic Hermite curve using the given algebraic coefficients A=[a3 a2 a1 a0], such that points on the curve are P(u)=sum_i(ai*u^i). More...
 
const Vec< 4, Vec3P > & getAlgebraicCoefficients () const
 Return a reference to the algebraic coefficients A=[a3 a2 a1 a0] that are stored in this object. More...
 
Vec< 4, Vec3PcalcGeometricCoefficients () const
 Calculate the Hermite coefficients H=[h0 h1 hu0 hu1] from the stored algebraic coefficients. More...
 
Vec3P evalP (RealP u) const
 Evaluate a point P(u) on this curve given a value for parameter u in [0,1]. More...
 
Vec3P evalPu (RealP u) const
 Evaluate the tangent Pu=dP/du on this curve given a value for parameter u in [0,1]. More...
 
Vec3P evalPuu (RealP u) const
 Evaluate the second derivative Puu=d2P/du2 on this curve given a value for parameter u in [0,1]. More...
 
Vec3P evalPuuu (RealP u) const
 Evaluate the third derivative Puuu=d3P/du3 on this curve. More...
 

Static Public Member Functions

Utility methods

These static methods provide operations useful for working with cubic Hermite curves.

static Row< 4, P > calcU (RealP u)
 Return the row vector U=[u^3 u^2 u 1]. More...
 
static Row< 4, P > calcFh (RealP u)
 Calculate the Hermite basis functions Fh=[F1..F4] for a given value of the parameter u. More...
 
static Row< 4, P > calcFhu (RealP u)
 Calculate first derivatives Fhu=[F1u..F4u] of the Hermite basis functions for a given value of the parameter u. More...
 
static Row< 4, P > calcFhuu (RealP u)
 Calculate second derivatives Fhuu=[F1uu..F4uu] of the Hermite basis functions for a given value of the parameter u. More...
 
static Row< 4, P > calcFhuuu (RealP u)
 Calculate third derivatives Fhuuu=[F1uuu..F4uuu] of the Hermite basis functions for a given value of the parameter u. More...
 
static Vec< 4, Vec3PcalcAFromH (const Vec< 4, Vec3P > &H)
 Given the Hermite coefficients H=~[h0 h1 hu0 hu1], return the algebraic coefficients A=~[a3 a2 a1 a0]. More...
 
static Vec< 4, Vec3PcalcHFromA (const Vec< 4, Vec3P > &A)
 Given the algebraic coefficients A=~[a3 a2 a1 a0], return the Hermite coefficients H=~[h0 h1 hu0 hu1]. More...
 
static Vec3P evalPUsingA (const Vec< 4, Vec3P > &A, RealP u)
 Given algebraic coefficients A and a value for the curve parameter u, return the point P(u) at that location. More...
 
static Vec3P evalPuUsingA (const Vec< 4, Vec3P > &A, RealP u)
 Given algebraic coefficients A and a value for the curve parameter u, return the first derivative Pu(u)=dP/du at that location. More...
 
static Vec3P evalPuuUsingA (const Vec< 4, Vec3P > &A, RealP u)
 Given algebraic coefficients A and a value for the curve parameter u, return the second derivative Puu(u)=d2P/du2 at that location. More...
 
static Vec3P evalPuuuUsingA (const Vec< 4, Vec3P > &A, RealP u)
 Given algebraic coefficients A and a value for the curve parameter u, return the third derivative Puuu(u)=d3P/du3 at that location. More...
 
static Vec3P evalPUsingH (const Vec< 4, Vec3P > &H, RealP u)
 Given Hermite coefficients H and a value for the curve parameter u, return the point P(u) at that location. More...
 
static Vec3P evalPuUsingH (const Vec< 4, Vec3P > &H, RealP u)
 Given Hermite coefficients H and a value for the curve parameter u, return the first derivative Pu(u)=dP/du at that location. More...
 
static Vec3P evalPuuUsingH (const Vec< 4, Vec3P > &H, RealP u)
 Given Hermite coefficients H and a value for the curve parameter u, return the second derivative Puu(u)=d2P/du2 at that location. More...
 
static Vec3P evalPuuuUsingH (const Vec< 4, Vec3P > &H, RealP u)
 Given Hermite coefficients H and a value for the curve parameter u, return the third derivative Puuu(u)=d3P/du3 at that location. More...
 
static Mat< 4, 4, P > getMh ()
 Obtain the Hermite basis matrix Mh explicitly. More...
 
static Vec< 4, P > multiplyByMh (const Vec< 4, P > &v)
 Form the product of the Hermite basis matrix Mh and a 4-vector, exploiting the structure of Mh (which is not symmetric). More...
 
static Mat< 4, 4, P > getMhInv ()
 Obtain the inverse inv(Mh) of the Hermite basis matrix explicitly. More...
 
static Vec< 4, P > multiplyByMhInv (const Vec< 4, P > &v)
 Form the product of the inverse Hermite basis matrix inv(Mh) and a 4-vector, exploiting the structure of inv(Mh) (which is not symmetric). More...
 

Detailed Description

template<class P>
class SimTK::Geo::CubicHermiteCurve_< P >

A primitive useful for computations involving a single cubic Hermite curve segment in algebraic or geometric (Hermite) form.

Objects of this class contain the algebraic coefficients because most operations are more efficient in that form, but methods are provided for easy conversion to or from Hermite form and for working directly with the Hermite form.

Note that a cubic Hermite spline (made up of multiple segments) would not necessarily be composed of these because they can be constructed more compactly with shared end points. However, the primitive and inline methods here can be used for fast curve segment computations.

Theory

The primary reference for this implementation is the book "Geometric Modeling, 3rd ed." by Michael E. Mortenson, Industrial Press 2006, chapter 3. We follow Mortenson's notation here (with a few exceptions) and equation numbers are from the text. We're using h's for the Hermite coefficients rather than Mortenson's b's to avoid confusion with Bezier control points B, so that we can use A for algebraic, H for Hermite, and B for Bezier coefficient matrices.

The curve is parameterized by a scalar u in [0..1], such that points on the curve, and their derivatives with respect to u are given by

    P(u)   = a3 u^3 + a2 u^2 +   a1 u +   a0                               (3.2)
    Pu(u)  =        3 a3 u^2 + 2 a2 u +   a1
    Puu(u) =                   6 a3 u + 2 a2
    Puuu(u) =                           6 a3

where Pu=dP/du, Puu=d2P/du2, Puuu=d3P/du3. Note that all higher derivatives are zero for a cubic. The 3-vectors ai are the algebraic coefficients, and that is the algebraic form of this cubic curve. The Hermite, or geometric, form is parameterized by position and tangent at the end points, given by

    h0=P(0)=a0, h1=P(1)=a3+a2+a1+a0, hu0=Pu(0)=a1, hu1=Pu(1)=3*a3+2*a2+a1

These define the Hermite coefficients h0, h1, hu0, hu1. In this form the curve's points are

 
    P(u)    =    F1(u) h0 +    F2(u) h1 +    F3(u) hu0 +    F4(u) hu1      (3.6)
    Pu(u)   =   F1u(u) h0 +   F2u(u) h1 +   F3u(u) hu0 +   F4u(u) hu1
    Puu(u)  =  F1uu(u) h0 +  F2uu(u) h1 +  F3uu(u) hu0 +  F4uu(u) hu1
    Puuu(u) = F1uuu(u) h0 + F2uuu(u) h1 + F3uuu(u) hu0 + F4uuu(u) hu1

where the Fi's are the (scalar) Hermite basis functions given by

    F1(u) =  2 u^3 - 3 u^2     + 1
    F2(u) = -2 u^3 + 3 u^2                                                 (3.4)
    F3(u) =    u^3 - 2 u^2 + u
    F4(u) =    u^3 -   u^2
    F1u(u) =  6 u^2 - 6 u       F1uu(u) =  12 u - 6   F1uuu(u) =  12       (3.7)
    F2u(u) = -6 u^2 + 6 u       F2uu(u) = -12 u + 6   F2uuu(u) = -12       (3.8)
    F3u(u) =  3 u^2 - 4 u + 1   F3uu(u) =   6 u - 4   F3uuu(u) = 6
    F4u(u) =  3 u^2 - 2 u       F4uu(u) =   6 u - 2   F4uuu(u) = 6

In matrix notation, let Fh=[F1 F2 F3 F4], and U=[u^3 u^2 u 1]. Then Fh = U Mh where Mh, the Hermite basis transformation matrix, and its inverse are:

         [ 2 -2  1  1 ]             [ 0  0  0  1 ]
    Mh = [-3  3 -2 -1 ]   inv(Mh) = [ 1  1  1  1 ]                        (3.18)
         [ 0  0  1  0 ]             [ 0  0  1  0 ]                        (3.23)
         [ 1  0  0  0 ]             [ 3  2  1  0 ]

(Mortenson calls this matrix "Mf".) Now we can write the algebraic and Hermite forms in matrix notation. Let A=~[a3 a2 a1 a0], H=~[h0 h1 hu0 hu1]. We have

    P(u) = U A 
         = U Mh H
       A = Mh H                                                        (3.20-22)
       H = inv(Mh) A

where the last two equations show how to convert between the algebraic and geometric forms. Note that while U, Fh, and Mh are ordinary matrices, A and H are hypermatrices since their elements are 3-vectors.

Because of the sparsity of the matrices and the many common subexpressions above, it saves a considerable amount of computation to work out the necessary products by hand, and this implementation does that. For example, to find the algebraic coefficients A given the Hermite coefficients H the matrix-vector multiply Mh*H would take 3x28=84 flops, while the hand-worked version is:

       [ a3 ]   [ 2 (h0 - h1) +   hu0 + hu1 ]
   A = [ a2 ] = [-3 (h0 - h1) - 2 hu0 - hu1 ]
       [ a1 ]   [           hu0             ]                      
       [ a0 ]   [           h0              ]

which instead takes 3x8=24 flops, 3.5X faster.

See also
CubicBezierCurve_, BicubicHermitePatch_, BicubicBezierPatch_

Constructor & Destructor Documentation

◆ CubicHermiteCurve_() [1/2]

template<class P >
SimTK::Geo::CubicHermiteCurve_< P >::CubicHermiteCurve_ ( )
inline

Construct an uninitialized curve; coefficients will be garbage.

◆ CubicHermiteCurve_() [2/2]

template<class P >
SimTK::Geo::CubicHermiteCurve_< P >::CubicHermiteCurve_ ( const Vec< 4, Vec3P > &  A)
inlineexplicit

Construct a cubic Hermite curve using the given algebraic coefficients A=[a3 a2 a1 a0], such that points on the curve are P(u)=sum_i(ai*u^i).

If you have Hermite coefficients H, convert them to algebraic using static method calcAFromH().

Member Function Documentation

◆ getAlgebraicCoefficients()

template<class P >
const Vec<4,Vec3P>& SimTK::Geo::CubicHermiteCurve_< P >::getAlgebraicCoefficients ( ) const
inline

Return a reference to the algebraic coefficients A=[a3 a2 a1 a0] that are stored in this object.

◆ calcGeometricCoefficients()

template<class P >
Vec<4,Vec3P> SimTK::Geo::CubicHermiteCurve_< P >::calcGeometricCoefficients ( ) const
inline

Calculate the Hermite coefficients H=[h0 h1 hu0 hu1] from the stored algebraic coefficients.

Here h0=P(0), h1=P(1), hu0=(dP/du)(0), hu1=(dP/du)(1) where P(u) is the curve evaluation function. Cost is 21 flops.

◆ evalP()

template<class P >
Vec3P SimTK::Geo::CubicHermiteCurve_< P >::evalP ( RealP  u) const
inline

Evaluate a point P(u) on this curve given a value for parameter u in [0,1].

Values outside this range are permitted but do not lie on the curve segment. Cost is 20 flops.

◆ evalPu()

template<class P >
Vec3P SimTK::Geo::CubicHermiteCurve_< P >::evalPu ( RealP  u) const
inline

Evaluate the tangent Pu=dP/du on this curve given a value for parameter u in [0,1].

Values outside this range are permitted but do not lie on the curve segment. Cost is 15 flops.

◆ evalPuu()

template<class P >
Vec3P SimTK::Geo::CubicHermiteCurve_< P >::evalPuu ( RealP  u) const
inline

Evaluate the second derivative Puu=d2P/du2 on this curve given a value for parameter u in [0,1].

Values outside this range are permitted but do not lie on the curve segment. Cost is 10 flops.

◆ evalPuuu()

template<class P >
Vec3P SimTK::Geo::CubicHermiteCurve_< P >::evalPuuu ( RealP  u) const
inline

Evaluate the third derivative Puuu=d3P/du3 on this curve.

Parameter u is ignored here since the 3rd derivative of a cubic curve is a constant. Cost is 3 flops.

◆ calcU()

template<class P >
static Row<4,P> SimTK::Geo::CubicHermiteCurve_< P >::calcU ( RealP  u)
inlinestatic

Return the row vector U=[u^3 u^2 u 1].

Cost is 2 flops.

◆ calcFh()

template<class P >
static Row<4,P> SimTK::Geo::CubicHermiteCurve_< P >::calcFh ( RealP  u)
inlinestatic

Calculate the Hermite basis functions Fh=[F1..F4] for a given value of the parameter u.

This is an optimized calculation of U*Mh, taking 10 flops.

◆ calcFhu()

template<class P >
static Row<4,P> SimTK::Geo::CubicHermiteCurve_< P >::calcFhu ( RealP  u)
inlinestatic

Calculate first derivatives Fhu=[F1u..F4u] of the Hermite basis functions for a given value of the parameter u.

Cost is 10 flops.

◆ calcFhuu()

template<class P >
static Row<4,P> SimTK::Geo::CubicHermiteCurve_< P >::calcFhuu ( RealP  u)
inlinestatic

Calculate second derivatives Fhuu=[F1uu..F4uu] of the Hermite basis functions for a given value of the parameter u.

Cost is 6 flops.

◆ calcFhuuu()

template<class P >
static Row<4,P> SimTK::Geo::CubicHermiteCurve_< P >::calcFhuuu ( RealP  u)
inlinestatic

Calculate third derivatives Fhuuu=[F1uuu..F4uuu] of the Hermite basis functions for a given value of the parameter u.

For a cubic curve the third derivative is a constants so the cost is 0 flops.

◆ calcAFromH()

template<class P >
static Vec<4,Vec3P> SimTK::Geo::CubicHermiteCurve_< P >::calcAFromH ( const Vec< 4, Vec3P > &  H)
inlinestatic

Given the Hermite coefficients H=~[h0 h1 hu0 hu1], return the algebraic coefficients A=~[a3 a2 a1 a0].

All coefficients are 3-vectors. Cost is 24 flops.

◆ calcHFromA()

template<class P >
static Vec<4,Vec3P> SimTK::Geo::CubicHermiteCurve_< P >::calcHFromA ( const Vec< 4, Vec3P > &  A)
inlinestatic

Given the algebraic coefficients A=~[a3 a2 a1 a0], return the Hermite coefficients H=~[h0 h1 hu0 hu1].

All coefficients are 3-vectors. Cost is 21 flops.

◆ evalPUsingA()

template<class P >
static Vec3P SimTK::Geo::CubicHermiteCurve_< P >::evalPUsingA ( const Vec< 4, Vec3P > &  A,
RealP  u 
)
inlinestatic

Given algebraic coefficients A and a value for the curve parameter u, return the point P(u) at that location.

Cost is 20 flops.

◆ evalPuUsingA()

template<class P >
static Vec3P SimTK::Geo::CubicHermiteCurve_< P >::evalPuUsingA ( const Vec< 4, Vec3P > &  A,
RealP  u 
)
inlinestatic

Given algebraic coefficients A and a value for the curve parameter u, return the first derivative Pu(u)=dP/du at that location.

Cost is 15 flops.

◆ evalPuuUsingA()

template<class P >
static Vec3P SimTK::Geo::CubicHermiteCurve_< P >::evalPuuUsingA ( const Vec< 4, Vec3P > &  A,
RealP  u 
)
inlinestatic

Given algebraic coefficients A and a value for the curve parameter u, return the second derivative Puu(u)=d2P/du2 at that location.

Cost is 10 flops.

◆ evalPuuuUsingA()

template<class P >
static Vec3P SimTK::Geo::CubicHermiteCurve_< P >::evalPuuuUsingA ( const Vec< 4, Vec3P > &  A,
RealP  u 
)
inlinestatic

Given algebraic coefficients A and a value for the curve parameter u, return the third derivative Puuu(u)=d3P/du3 at that location.

The parameter u is ignored since the third derivative of a cubic is just a constant. Cost is 3 flops.

◆ evalPUsingH()

template<class P >
static Vec3P SimTK::Geo::CubicHermiteCurve_< P >::evalPUsingH ( const Vec< 4, Vec3P > &  H,
RealP  u 
)
inlinestatic

Given Hermite coefficients H and a value for the curve parameter u, return the point P(u) at that location.

Cost is 31 flops. Note that if you need to do this for the same curve more than twice, it is cheaper to convert to algebraic form using calcAFromH() (24 flops) and then evaluate using A (20 flops).

◆ evalPuUsingH()

template<class P >
static Vec3P SimTK::Geo::CubicHermiteCurve_< P >::evalPuUsingH ( const Vec< 4, Vec3P > &  H,
RealP  u 
)
inlinestatic

Given Hermite coefficients H and a value for the curve parameter u, return the first derivative Pu(u)=dP/du at that location.

Cost is 31 flops. Note that if you need to do this for the same curve more than once, it is cheaper to convert to algebraic form using calcAFromH() (24 flops) and then evaluate using A (15 flops).

◆ evalPuuUsingH()

template<class P >
static Vec3P SimTK::Geo::CubicHermiteCurve_< P >::evalPuuUsingH ( const Vec< 4, Vec3P > &  H,
RealP  u 
)
inlinestatic

Given Hermite coefficients H and a value for the curve parameter u, return the second derivative Puu(u)=d2P/du2 at that location.

Cost is 27 flops. Note that if you need to do this for the same curve more than once, it is cheaper to convert to algebraic form using calcAFromH() (24 flops) and then evaluate using A (10 flops).

◆ evalPuuuUsingH()

template<class P >
static Vec3P SimTK::Geo::CubicHermiteCurve_< P >::evalPuuuUsingH ( const Vec< 4, Vec3P > &  H,
RealP  u 
)
inlinestatic

Given Hermite coefficients H and a value for the curve parameter u, return the third derivative Puuu(u)=d3P/du3 at that location.

Cost is 21 flops. Note that if you need to do this for the same curve more than once, it is cheaper to convert to algebraic form using calcAFromH() (24 flops) and then evaluate using A (3 flops).

◆ getMh()

template<class P >
static Mat<4,4,P> SimTK::Geo::CubicHermiteCurve_< P >::getMh ( )
inlinestatic

Obtain the Hermite basis matrix Mh explicitly.

This is mostly useful for testing since specialized routines can save a lot of CPU time over working directly in matrix form. This is a constant matrix so there is no computation cost.

◆ multiplyByMh()

template<class P >
static Vec<4,P> SimTK::Geo::CubicHermiteCurve_< P >::multiplyByMh ( const Vec< 4, P > &  v)
inlinestatic

Form the product of the Hermite basis matrix Mh and a 4-vector, exploiting the structure of Mh (which is not symmetric).

Cost is 8 flops.

◆ getMhInv()

template<class P >
static Mat<4,4,P> SimTK::Geo::CubicHermiteCurve_< P >::getMhInv ( )
inlinestatic

Obtain the inverse inv(Mh) of the Hermite basis matrix explicitly.

This is mostly useful for testing since specialized routines can save a lot of CPU time over working directly in matrix form. This is a constant matrix so there is no computation cost.

◆ multiplyByMhInv()

template<class P >
static Vec<4,P> SimTK::Geo::CubicHermiteCurve_< P >::multiplyByMhInv ( const Vec< 4, P > &  v)
inlinestatic

Form the product of the inverse Hermite basis matrix inv(Mh) and a 4-vector, exploiting the structure of inv(Mh) (which is not symmetric).

Cost is 7 flops.


The documentation for this class was generated from the following files: