Simbody  3.4 (development)
Geo_CubicHermiteCurve.h
Go to the documentation of this file.
00001 #ifndef SimTK_SIMMATH_GEO_CUBIC_HERMITE_CURVE_H_
00002 #define SimTK_SIMMATH_GEO_CUBIC_HERMITE_CURVE_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                        Simbody(tm): SimTKmath                              *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK biosimulation toolkit originating from           *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody.  *
00011  *                                                                            *
00012  * Portions copyright (c) 2011-12 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
00017  * not use this file except in compliance with the License. You may obtain a  *
00018  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
00019  *                                                                            *
00020  * Unless required by applicable law or agreed to in writing, software        *
00021  * distributed under the License is distributed on an "AS IS" BASIS,          *
00022  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
00023  * See the License for the specific language governing permissions and        *
00024  * limitations under the License.                                             *
00025  * -------------------------------------------------------------------------- */
00026 
00031 #include "SimTKcommon.h"
00032 #include "simmath/internal/common.h"
00033 #include "simmath/internal/Geo.h"
00034 
00035 #include <cassert>
00036 #include <cmath>
00037 #include <algorithm>
00038 
00039 namespace SimTK {
00040 
00041 
00042 //==============================================================================
00043 //                         GEO CUBIC HERMITE CURVE
00044 //==============================================================================
00130 template <class P>
00131 class Geo::CubicHermiteCurve_ {
00132 typedef P               RealP;
00133 typedef Vec<3,RealP>    Vec3P;
00134 
00135 public:
00137 CubicHermiteCurve_() {}
00142 explicit CubicHermiteCurve_(const Vec<4,Vec3P>& A) : A(A) {} 
00145 const Vec<4,Vec3P>& getAlgebraicCoefficients() const {return A;}
00149 Vec<4,Vec3P> calcGeometricCoefficients() const {return calcHFromA(A);}
00153 Vec3P evalP(RealP u) const {return evalPUsingA(A,u);}
00157 Vec3P evalPu(RealP u) const {return evalPuUsingA(A,u);}
00161 Vec3P evalPuu(RealP u) const {return evalPuuUsingA(A,u);}
00165 Vec3P evalPuuu(RealP u) const {return evalPuuuUsingA(A,u);}
00166 
00172 static Row<4,P> calcU(RealP u) {
00173     const RealP u2 = u*u;
00174     return Row<4,P>(u*u2, u2, u, 1);
00175 }
00176 
00179 static Row<4,P> calcFh(RealP u) {
00180     const RealP u2 = u*u, u3 = u*u2;
00181     const RealP t = 3*u2 - 2*u3;
00182     return Row<4,P>(1-t, t, u3-2*u2+u, u3-u2); 
00183 }
00184 
00187 static Row<4,P> calcFhu(RealP u) {
00188     const RealP u2 = u*u, u23=3*u2;
00189     const RealP dt = 6*(u-u2);
00190     return Row<4,P>(-dt, dt, u23-4*u+1, u23-2*u); 
00191 }
00192 
00195 static Row<4,P> calcFhuu(RealP u) {
00196     const RealP u6  = 6*u;
00197     const RealP ddt = 6 - 12*u;
00198     return Row<4,P>(-ddt, ddt, u6-4, u6-2); 
00199 }
00200 
00204 static Row<4,P> calcFhuuu(RealP u) {
00205     return Row<4,P>(12, -12, 6, 6); 
00206 }
00207 
00211 static Vec<4,Vec3P> calcAFromH(const Vec<4,Vec3P>& H) {
00212     const Vec3P& h0= H[0]; const Vec3P& h1= H[1];    // aliases for beauty
00213     const Vec3P& hu0=H[2]; const Vec3P& hu1=H[3];
00214     const Vec3P h01 = h0 - h1;
00215     return Vec<4,Vec3P>( 2*h01 +   hu0 + hu1,
00216                         -3*h01 - 2*hu0 - hu1,
00217                          hu0,
00218                          h0 );
00219 }
00220 
00224 static Vec<4,Vec3P> calcHFromA(const Vec<4,Vec3P>& A) {
00225     const Vec3P& a3=A[0]; const Vec3P& a2=A[1];    // aliases for beauty
00226     const Vec3P& a1=A[2]; const Vec3P& a0=A[3];
00227     return Vec<4,Vec3P>(a0, a3+a2+a1+a0, a1, 3*a3+2*a2+a1);
00228 }
00229 
00232 static Vec3P evalPUsingA(const Vec<4,Vec3P>& A, RealP u) { 
00233     const RealP u2 = u*u, u3 = u*u2;
00234     return u3*A[0] + u2*A[1] + u*A[2] + A[3]; // (vectors)
00235 }
00238 static Vec3P evalPuUsingA(const Vec<4,Vec3P>& A, RealP u) { 
00239     return (3*u*u)*A[0] + (2*u)*A[1] + A[2];
00240 }
00243 static Vec3P evalPuuUsingA(const Vec<4,Vec3P>& A, RealP u) { 
00244     return (6*u)*A[0] + 2*A[1];
00245 }
00250 static Vec3P evalPuuuUsingA(const Vec<4,Vec3P>& A, RealP u) { 
00251     return 6*A[0];
00252 }
00253 
00259 static Vec3P evalPUsingH(const Vec<4,Vec3P>& H, RealP u) { 
00260     return calcFh(u)*H; // 10 + 3*7 = 31 flops
00261 }
00267 static Vec3P evalPuUsingH(const Vec<4,Vec3P>& H, RealP u) { 
00268     return calcFhu(u)*H; // 10 + 3*7 = 31 flops
00269 }
00275 static Vec3P evalPuuUsingH(const Vec<4,Vec3P>& H, RealP u) { 
00276     return calcFhuu(u)*H; // 6 + 3*7 = 27 flops
00277 }
00283 static Vec3P evalPuuuUsingH(const Vec<4,Vec3P>& H, RealP u) { 
00284     return calcFhuuu(u)*H; // 0 + 3*7 = 21 flops
00285 }
00286 
00291 static Mat<4,4,P> getMh() {
00292     return Mat<4,4,P>( 2, -2,  1,  1,
00293                       -3,  3, -2, -1,
00294                        0,  0,  1,  0,
00295                        1,  0,  0,  0 );
00296 }
00297 
00300 static Vec<4,P> multiplyByMh(const Vec<4,P>& v) {
00301     const RealP v0=v[0], v1=v[1], v2=v[2], v3=v[3];
00302     const RealP v01 = v0-v1;
00303     return Vec<4,P>(2*v01+v2+v3, -3*v01-2*v2-v3, v2, v0);
00304 }
00305 
00310 static Mat<4,4,P> getMhInv() {
00311     return Mat<4,4,P>( 0,  0,  0,  1,
00312                        1,  1,  1,  1,
00313                        0,  0,  1,  0,
00314                        3,  2,  1,  0 );
00315 }
00316 
00320 static Vec<4,P> multiplyByMhInv(const Vec<4,P>& v) {
00321     const RealP v0=v[0], v1=v[1], v2=v[2], v3=v[3];
00322     return Vec<4,P>(v3, v0+v1+v2+v3, v2, 3*v0+2*v1+v2);
00323 }
00326 private:
00327 Vec<4,Vec3P> A;
00328 };
00329 
00330 
00331 
00332 } // namespace SimTK
00333 
00334 #endif // SimTK_SIMMATH_GEO_CUBIC_HERMITE_CURVE_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines