Simbody  3.4 (development)
Geo_BicubicHermitePatch.h
Go to the documentation of this file.
00001 #ifndef SimTK_SIMMATH_GEO_BICUBIC_HERMITE_PATCH_H_
00002 #define SimTK_SIMMATH_GEO_BICUBIC_HERMITE_PATCH_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 BICUBIC HERMITE PATCH
00044 //==============================================================================
00096 template <class P>
00097 class Geo::BicubicHermitePatch_ {
00098 typedef P               RealP;
00099 typedef Vec<3,RealP>    Vec3P;
00100 
00101 public:
00103 BicubicHermitePatch_() {}
00105 explicit BicubicHermitePatch_(const Mat<4,4,Vec3P>& A) : A(A) {} 
00109 const Mat<4,4,Vec3P>& getAlgebraicCoefficients() const {return A;}
00113 Mat<4,4,Vec3P> calcHermiteCoefficients() const {return calcHFromA(A);}
00114 
00118 Vec3P evalP(RealP u, RealP w) const {return evalPUsingA(A,u,w);}
00119 
00123 void evalP1(RealP u, RealP w, Vec3P& Pu, Vec3P& Pw) const 
00124 {   return evalP1UsingA(A,u,w,Pu,Pw); }
00125 
00130 void evalP2(RealP u, RealP w, Vec3P& Puu, Vec3P& Puw, Vec3P& Pww) const 
00131 {   evalP2UsingA(A,u,w,Puu,Puw,Pww); }
00132 
00137 void evalP3(RealP u, RealP w, Vec3P& Puuu, Vec3P& Puuw, 
00138                               Vec3P& Puww, Vec3P& Pwww) const 
00139 {   evalP3UsingA(A,u,w,Puuu,Puuw,Puww,Pwww); }
00140 
00147 static Mat<4,4,Vec3P> calcAFromH(const Mat<4,4,Vec3P>& H) {
00148     typedef const Vec3P& Coef;
00149     Coef h00=H(0,0), h01=H(0,1), w00=H(0,2), w01=H(0,3), 
00150          h10=H(1,0), h11=H(1,1), w10=H(1,2), w11=H(1,3), 
00151          u00=H(2,0), u01=H(2,1), t00=H(2,2), t01=H(2,3), 
00152          u10=H(3,0), u11=H(3,1), t10=H(3,2), t11=H(3,3); 
00153     // First calculate Mh*H:
00154     //       a   b   c   d
00155     //       p   q   r   s
00156     //      u00 u01 t00 t01
00157     //      h00 h01 w00 w01
00158     Vec3P a=2*(h00-h10)+u00+u10,   b=2*(h01-h11)+u01+u11,
00159           c=2*(w00-w10)+t00+t10,   d=2*(w01-w11)+t01+t11;
00160     Vec3P p=3*(h10-h00)-2*u00-u10, q=3*(h11-h01)-2*u01-u11,
00161           r=3*(w10-w00)-2*t00-t10, s=3*(w11-w01)-2*t01-t11;
00162 
00163     // Then calculate (Mh*H)*~Mh.
00164     Vec3P bma=b-a, qmp=q-p;
00165     return Mat<4,4,Vec3P>
00166        (     c+d-2*bma,            3*bma-2*c-d,        c,   a,
00167              r+s-2*qmp,            3*qmp-2*r-s,        r,   p,
00168         2*(u00-u01)+t00+t01,  3*(u01-u00)-2*t00-t01,  t00, u00,
00169         2*(h00-h01)+w00+w01,  3*(h01-h00)-2*w00-w01,  w00, h00  );
00170 }
00171 
00174 static Mat<4,4,Vec3P> calcHFromA(const Mat<4,4,Vec3P>& A) {
00175     typedef const Vec3P& Coef;
00176     Coef a33=A(0,0), a32=A(0,1), a31=A(0,2), a30=A(0,3), 
00177          a23=A(1,0), a22=A(1,1), a21=A(1,2), a20=A(1,3), 
00178          a13=A(2,0), a12=A(2,1), a11=A(2,2), a10=A(2,3), 
00179          a03=A(3,0), a02=A(3,1), a01=A(3,2), a00=A(3,3); 
00180     // First calculate Mh^-1*A:
00181     //      a03 a02 a01 a00
00182     //       a   b   c   d
00183     //      a13 a12 a11 a10
00184     //       p   q   r   s
00185     Vec3P a=a33+a23+a13+a03, b=a32+a22+a12+a02, // 3x12 flops
00186           c=a31+a21+a11+a01, d=a30+a20+a10+a00;
00187     Vec3P p=3*a33+2*a23+a13, q=3*a32+2*a22+a12, // 3x16 flops
00188           r=3*a31+2*a21+a11, s=3*a30+2*a20+a10;
00189 
00190     // Then calculate (Mh^-1*A)*Mh^-T (3x28 flops)
00191     return Mat<4,4,Vec3P>
00192        ( a00,  a03+a02+a01+a00,  a01,  3*a03+2*a02+a01,
00193           d,       a+b+c+d,       c,      3*a+2*b+c,
00194          a10,  a13+a12+a11+a10,  a11,  3*a13+2*a12+a11,
00195           s,       p+q+r+s,       r,      3*p+2*q+r     );
00196 }
00197 
00201 static Vec3P evalPUsingA(const Mat<4,4,Vec3P>& A, RealP u, RealP w) { 
00202     typedef const Vec3P& Coef;
00203     Coef a33=A(0,0), a32=A(0,1), a31=A(0,2), a30=A(0,3), 
00204          a23=A(1,0), a22=A(1,1), a21=A(1,2), a20=A(1,3), 
00205          a13=A(2,0), a12=A(2,1), a11=A(2,2), a10=A(2,3), 
00206          a03=A(3,0), a02=A(3,1), a01=A(3,2), a00=A(3,3); 
00207 
00208     const RealP u2 = u*u, u3 = u*u2, w2 = w*w, w3 = w*w2;
00209     Vec3P p =   u3*(a33*w3 + a32*w2 + a31*w + a30)
00210               + u2*(a23*w3 + a22*w2 + a21*w + a20)
00211               + u *(a13*w3 + a12*w2 + a11*w + a10)
00212               +    (a03*w3 + a02*w2 + a01*w + a00);
00213     return p;
00214 }
00215 
00219 static void evalP1UsingA(const Mat<4,4,Vec3P>& A, RealP u, RealP w,
00220                          Vec3P& Pu, Vec3P& Pw) {
00221     typedef const Vec3P& Coef;
00222     Coef a33=A(0,0), a32=A(0,1), a31=A(0,2), a30=A(0,3), 
00223          a23=A(1,0), a22=A(1,1), a21=A(1,2), a20=A(1,3), 
00224          a13=A(2,0), a12=A(2,1), a11=A(2,2), a10=A(2,3), 
00225          a03=A(3,0), a02=A(3,1), a01=A(3,2); 
00226 
00227     const RealP u2 = u*u, u3 = u*u2, w2 = w*w, w3 = w*w2;
00228     Pu =   3*u2*(a33*w3 + a32*w2 + a31*w + a30)
00229          + 2* u*(a23*w3 + a22*w2 + a21*w + a20)
00230          +      (a13*w3 + a12*w2 + a11*w + a10);
00231     Pw =   3*w2*(u3*a33 + u2*a23 + u*a13 + a03)
00232          + 2* w*(u3*a32 + u2*a22 + u*a12 + a02)
00233          +      (u3*a31 + u2*a21 + u*a11 + a01);
00234 }
00235 
00240 static void evalP2UsingA(const Mat<4,4,Vec3P>& A, RealP u, RealP w,
00241                          Vec3P& Puu, Vec3P& Puw, Vec3P& Pww) {
00242     typedef const Vec3P& Coef;
00243     Coef a33=A(0,0), a32=A(0,1), a31=A(0,2), a30=A(0,3), 
00244          a23=A(1,0), a22=A(1,1), a21=A(1,2), a20=A(1,3), 
00245          a13=A(2,0), a12=A(2,1), a11=A(2,2),
00246          a03=A(3,0), a02=A(3,1); 
00247 
00248     const RealP u2 = u*u, u3 = u*u2, w2 = w*w, w3 = w*w2;
00249     Puu =   6*u*(a33*w3 + a32*w2 + a31*w + a30)
00250           + 2  *(a23*w3 + a22*w2 + a21*w + a20);
00251     Pww =   6*w*(u3*a33 + u2*a23 + u*a13 + a03)
00252           + 2  *(u3*a32 + u2*a22 + u*a12 + a02);
00253     Puw =   3*u2*(3*a33*w2 + 2*a32*w + a31)
00254           + 2*u *(3*a23*w2 + 2*a22*w + a21)
00255           +      (3*a13*w2 + 2*a12*w + a11);
00256 }
00257 
00262 static void evalP3UsingA(const Mat<4,4,Vec3P>& A, RealP u, RealP w,
00263                          Vec3P& Puuu, Vec3P& Puuw, Vec3P& Puww, Vec3P& Pwww) {
00264     typedef const Vec3P& Coef;
00265     Coef a33=A(0,0), a32=A(0,1), a31=A(0,2), a30=A(0,3), 
00266          a23=A(1,0), a22=A(1,1), a21=A(1,2), a20=A(1,3), 
00267          a13=A(2,0), a12=A(2,1), 
00268          a03=A(3,0), a02=A(3,1); 
00269 
00270     const RealP u2 = u*u, u3 = u*u2, w2 = w*w, w3 = w*w2;
00271     Puuu = 6*(a33*w3 + a32*w2 + a31*w + a30);
00272     Pwww = 6*(u3*a33 + u2*a23 + u*a13 + a03);
00273     Puuw = 6*u*(3*a33*w2 + 2*a32*w + a31) 
00274            +    6*a23*w2 + 4*a22*w + 2*a21;
00275     Puww = 6*w*(3*u2*a33 + 2*u*a23 + a13) 
00276            +    6*u2*a32 + 4*u*a22 + 2*a12;
00277 }
00280 private:
00281 Mat<4,4,Vec3P> A;   // algebraic coefficients
00282 };
00283 
00284 
00285 
00286 } // namespace SimTK
00287 
00288 #endif // SimTK_SIMMATH_GEO_BICUBIC_HERMITE_PATCH_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines