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