Simbody
3.4 (development)
|
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_