Simbody  3.4 (development)
Geodesic.h
Go to the documentation of this file.
00001 #ifndef SimTK_SIMMATH_GEODESIC_H_
00002 #define SimTK_SIMMATH_GEODESIC_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) 2012 Stanford University and the Authors.           *
00013  * Authors: Ian Stavness, 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 
00030 //==============================================================================
00031 //                           GEODESIC CLASS
00032 //==============================================================================
00033 
00034 
00035 #include "SimTKcommon.h"
00036 #include "simmath/internal/common.h"
00037 
00038 namespace SimTK {
00039 
00051 class SimTK_SIMMATH_EXPORT Geodesic {
00052 public:
00054     Geodesic() {clear();}
00055 
00056     int getNumPoints() const {return (int)frenetFrames.size(); }
00057 
00066     const Array_<Transform>& getFrenetFrames() const {return frenetFrames;}
00067     Array_<Transform>&       updFrenetFrames() {return frenetFrames;}
00068     void addFrenetFrame(const Transform& Kf) {frenetFrames.push_back(Kf);}
00069 
00070     Array_<Real>& updArcLengths() {return arcLengths;}
00071     const Array_<Real>& getArcLengths() const {return arcLengths;}
00072     void addArcLength(Real s) {arcLengths.push_back(s);}
00073 
00074     Array_<Real>& updCurvatures() {return curvature;}
00075     const Array_<Real>& getCurvatures() const {return curvature;}
00076     void addCurvature(Real kappa) {curvature.push_back(kappa);}
00077 
00078     Array_<Vec2>& updDirectionalSensitivityPtoQ() 
00079     {   return directionalSensitivityPtoQ; }
00080     const Array_<Vec2>& getDirectionalSensitivityPtoQ() const 
00081     {   return directionalSensitivityPtoQ; }
00082     void addDirectionalSensitivityPtoQ(const Vec2& jP) {
00083         directionalSensitivityPtoQ.push_back(jP);
00084     }
00085 
00086     Array_<Vec2>& updDirectionalSensitivityQtoP() 
00087     {   return directionalSensitivityQtoP; }
00088     const Array_<Vec2>& getDirectionalSensitivityQtoP() const 
00089     {   return directionalSensitivityQtoP; }
00090     void addDirectionalSensitivityQtoP(const Vec2& jQ) {
00091         directionalSensitivityQtoP.push_back(jQ);
00092     }
00093 
00094     Array_<Vec2>& updPositionalSensitivityPtoQ() 
00095     {   return positionalSensitivityPtoQ; }
00096     const Array_<Vec2>& getPositionalSensitivityPtoQ() const 
00097     {   return positionalSensitivityPtoQ; }
00098     void addPositionalSensitivityPtoQ(const Vec2& jtP) {
00099         positionalSensitivityPtoQ.push_back(jtP);
00100     }
00101 
00102     Array_<Vec2>& updPositionalSensitivityQtoP() 
00103     {   return positionalSensitivityQtoP; }
00104     const Array_<Vec2>& getPositionalSensitivityQtoP() const 
00105     {   return positionalSensitivityQtoP; }
00106     void addPositionalSensitivityQtoP(const Vec2& jtQ) {
00107         positionalSensitivityQtoP.push_back(jtQ);
00108     }
00109 
00110     void setTorsionAtP(Real tauP) {torsionAtP = tauP;}
00111     void setTorsionAtQ(Real tauQ) {torsionAtQ = tauQ;}
00112     void setBinormalCurvatureAtP(Real muP) {binormalCurvatureAtP = muP;}
00113     void setBinormalCurvatureAtQ(Real muQ) {binormalCurvatureAtQ = muQ;}
00114 
00117     Real getLength() const {return arcLengths.empty() ? 0 : arcLengths.back();}
00118 
00124     Real calcLengthDot(const Vec3& xdotP, const Vec3& xdotQ) const 
00125     {   return ~xdotQ*getTangentQ() - ~xdotP*getTangentP(); }
00126 
00129     const Vec3& getPointP() const {return frenetFrames.front().p();}
00132     const Vec3& getPointQ() const {return frenetFrames.back().p();}
00133 
00137     const UnitVec3& getNormalP() const {return frenetFrames.front().z();}
00141     const UnitVec3& getNormalQ() const {return frenetFrames.back().z();}
00142 
00145     const UnitVec3& getTangentP() const {return frenetFrames.front().y();}
00148     const UnitVec3& getTangentQ() const {return frenetFrames.back().y();}
00149 
00152     const UnitVec3& getBinormalP() const {return frenetFrames.front().x();}
00155     const UnitVec3& getBinormalQ() const {return frenetFrames.back().x();}
00156 
00162     Real getCurvatureP() const {return curvature.front();}
00170     Real getCurvatureQ() const {return curvature.back();}
00171 
00176     Real getTorsionP() const {return torsionAtP;}
00181     Real getTorsionQ() const {return torsionAtQ;}
00182 
00186     Real getBinormalCurvatureP() const {return binormalCurvatureAtP;}
00190     Real getBinormalCurvatureQ() const {return binormalCurvatureAtQ;}
00191 
00197     Real getJacobiP() const {return directionalSensitivityQtoP.front()[0];}
00203     Real getJacobiQ() const {return directionalSensitivityPtoQ.back()[0];}
00204 
00207     // Note sign change here -- we calculated this by integrating backwards
00208     // so the arc length we used had the opposite sign from the true arc
00209     // length parameter.
00210     Real getJacobiPDot() const {return -directionalSensitivityQtoP.front()[1];}
00213     Real getJacobiQDot() const {return directionalSensitivityPtoQ.back()[1];}
00214 
00215     // XXX testing
00216     Real getJacobiTransP() const {return positionalSensitivityQtoP.front()[0];}
00217     Real getJacobiTransQ() const {return positionalSensitivityPtoQ.back()[0];}
00218     Real getJacobiTransPDot() const {return -positionalSensitivityQtoP.front()[1];}
00219     Real getJacobiTransQDot() const {return positionalSensitivityPtoQ.back()[1];}
00220 
00223     void clear() {
00224         arcLengths.clear();
00225         frenetFrames.clear(); 
00226         directionalSensitivityPtoQ.clear(); 
00227         directionalSensitivityQtoP.clear(); 
00228         positionalSensitivityPtoQ.clear(); 
00229         positionalSensitivityQtoP.clear(); 
00230         curvature.clear();
00231         torsionAtP = torsionAtQ = NaN;
00232         binormalCurvatureAtP = binormalCurvatureAtQ = NaN;
00233         convexFlag = shortestFlag = false;
00234         initialStepSizeHint = achievedAccuracy = NaN;
00235     }
00236 
00237     void setIsConvex(bool isConvex) {convexFlag = isConvex;}
00238     void setIsShortest(bool isShortest) {shortestFlag = isShortest;}
00239     void setInitialStepSizeHint(Real sz) {initialStepSizeHint=sz;} 
00240     void setAchievedAccuracy(Real acc) {achievedAccuracy=acc;} 
00241 
00242     bool isConvex() const {return convexFlag;}
00243     bool isShortest() const {return shortestFlag;}
00244     Real getInitialStepSizeHint() const {return initialStepSizeHint;}
00245     Real getAchievedAccuracy() const {return achievedAccuracy;}
00246 
00247     void dump(std::ostream& o) const;
00248 
00249 private:
00250     // All these arrays are the same length when the geodesic is complete.
00251     Array_<Real>      arcLengths; // arc length coord corresponding to point
00252     Array_<Transform> frenetFrames; // see above for more info
00253     Array_<Vec2>      directionalSensitivityPtoQ; // jQ and jQdot
00254     Array_<Vec2>      directionalSensitivityQtoP; // jP and -jPdot
00255     Array_<Vec2>      positionalSensitivityPtoQ; // jtQ and jtQdot
00256     Array_<Vec2>      positionalSensitivityQtoP; // jtP and -jtPdot
00257     Array_<Real>      curvature; // normal curvature kappa in tangent direction
00258     // These are only calculated at the end points.
00259     Real              torsionAtP, torsionAtQ; // torsion tau (only at ends) 
00260     Real              binormalCurvatureAtP, binormalCurvatureAtQ;
00261 
00262     // This flag is set true if curvature[i]>=0 for all i.
00263     bool convexFlag; // is this geodesic over a convex surface?
00264 
00265     bool shortestFlag; // XXX is this geodesic the shortest one of the surface?
00266     Real initialStepSizeHint; // the initial step size to be tried when integrating this geodesic
00267     Real achievedAccuracy; // the accuracy to which this geodesic curve has been calculated
00268 };
00269 
00270 
00274 class GeodesicDecorator : public DecorationGenerator {
00275 public:
00276     GeodesicDecorator(const Geodesic& geod, const Vec3& color) :
00277             m_geod(geod), m_color(color) { }
00278 
00279     virtual void generateDecorations(const State& state,
00280             Array_<DecorativeGeometry>& geometry) {
00281 //        m_system.realize(state, Stage::Position);
00282 
00283         // draw connected line segments from pts
00284         const Array_<Transform>& Kfs = m_geod.getFrenetFrames();
00285         Vec3 prevPt;
00286         for (int i = 0; i < (int) Kfs.size(); ++i) {
00287             Vec3 cur = Kfs[i].p();
00288             if (i > 0) {
00289                 geometry.push_back(
00290                         DecorativeLine(prevPt, cur)
00291                         .setColor(m_color)
00292                         .setLineThickness(3));
00293             }
00294             prevPt = cur;
00295 
00296             geometry.push_back(DecorativeFrame(Real(.2)).setTransform(Kfs[i]));
00297         }
00298     }
00299 
00300 private:
00301     const Geodesic& m_geod;
00302     const Vec3& m_color;
00303 };
00304 
00305 
00306 
00307 
00311 class GeodesicOptions {
00312     // XXX stub
00313 };
00314 
00315 
00316 } // namespace SimTK
00317 
00318 #endif // SimTK_SIMMATH_GEODESIC_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines