Simbody  3.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Geodesic.h
Go to the documentation of this file.
1 #ifndef SimTK_SIMMATH_GEODESIC_H_
2 #define SimTK_SIMMATH_GEODESIC_H_
3 
4 /* -------------------------------------------------------------------------- *
5  * Simbody(tm): SimTKmath *
6  * -------------------------------------------------------------------------- *
7  * This is part of the SimTK biosimulation toolkit originating from *
8  * Simbios, the NIH National Center for Physics-Based Simulation of *
9  * Biological Structures at Stanford, funded under the NIH Roadmap for *
10  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11  * *
12  * Portions copyright (c) 2012 Stanford University and the Authors. *
13  * Authors: Ian Stavness, Michael Sherman *
14  * Contributors: *
15  * *
16  * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17  * not use this file except in compliance with the License. You may obtain a *
18  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19  * *
20  * Unless required by applicable law or agreed to in writing, software *
21  * distributed under the License is distributed on an "AS IS" BASIS, *
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23  * See the License for the specific language governing permissions and *
24  * limitations under the License. *
25  * -------------------------------------------------------------------------- */
26 
30 //==============================================================================
31 // GEODESIC CLASS
32 //==============================================================================
33 
34 
35 #include "SimTKcommon.h"
37 
38 namespace SimTK {
39 
52 public:
54  Geodesic() {clear();}
55 
56  int getNumPoints() const {return (int)frenetFrames.size(); }
57 
66  const Array_<Transform>& getFrenetFrames() const {return frenetFrames;}
67  Array_<Transform>& updFrenetFrames() {return frenetFrames;}
68  void addFrenetFrame(const Transform& Kf) {frenetFrames.push_back(Kf);}
69 
70  Array_<Real>& updArcLengths() {return arcLengths;}
71  const Array_<Real>& getArcLengths() const {return arcLengths;}
72  void addArcLength(Real s) {arcLengths.push_back(s);}
73 
74  Array_<Real>& updCurvatures() {return curvature;}
75  const Array_<Real>& getCurvatures() const {return curvature;}
76  void addCurvature(Real kappa) {curvature.push_back(kappa);}
77 
78  Array_<Vec2>& updDirectionalSensitivityPtoQ()
79  { return directionalSensitivityPtoQ; }
80  const Array_<Vec2>& getDirectionalSensitivityPtoQ() const
81  { return directionalSensitivityPtoQ; }
83  directionalSensitivityPtoQ.push_back(jP);
84  }
85 
86  Array_<Vec2>& updDirectionalSensitivityQtoP()
87  { return directionalSensitivityQtoP; }
88  const Array_<Vec2>& getDirectionalSensitivityQtoP() const
89  { return directionalSensitivityQtoP; }
91  directionalSensitivityQtoP.push_back(jQ);
92  }
93 
94  Array_<Vec2>& updPositionalSensitivityPtoQ()
95  { return positionalSensitivityPtoQ; }
96  const Array_<Vec2>& getPositionalSensitivityPtoQ() const
97  { return positionalSensitivityPtoQ; }
99  positionalSensitivityPtoQ.push_back(jtP);
100  }
101 
102  Array_<Vec2>& updPositionalSensitivityQtoP()
103  { return positionalSensitivityQtoP; }
104  const Array_<Vec2>& getPositionalSensitivityQtoP() const
105  { return positionalSensitivityQtoP; }
107  positionalSensitivityQtoP.push_back(jtQ);
108  }
109 
110  void setTorsionAtP(Real tauP) {torsionAtP = tauP;}
111  void setTorsionAtQ(Real tauQ) {torsionAtQ = tauQ;}
112  void setBinormalCurvatureAtP(Real muP) {binormalCurvatureAtP = muP;}
113  void setBinormalCurvatureAtQ(Real muQ) {binormalCurvatureAtQ = muQ;}
114 
117  Real getLength() const {return arcLengths.empty() ? 0 : arcLengths.back();}
118 
124  Real calcLengthDot(const Vec3& xdotP, const Vec3& xdotQ) const
125  { return ~xdotQ*getTangentQ() - ~xdotP*getTangentP(); }
126 
129  const Vec3& getPointP() const {return frenetFrames.front().p();}
132  const Vec3& getPointQ() const {return frenetFrames.back().p();}
133 
137  const UnitVec3& getNormalP() const {return frenetFrames.front().z();}
141  const UnitVec3& getNormalQ() const {return frenetFrames.back().z();}
142 
145  const UnitVec3& getTangentP() const {return frenetFrames.front().y();}
148  const UnitVec3& getTangentQ() const {return frenetFrames.back().y();}
149 
152  const UnitVec3& getBinormalP() const {return frenetFrames.front().x();}
155  const UnitVec3& getBinormalQ() const {return frenetFrames.back().x();}
156 
162  Real getCurvatureP() const {return curvature.front();}
170  Real getCurvatureQ() const {return curvature.back();}
171 
176  Real getTorsionP() const {return torsionAtP;}
181  Real getTorsionQ() const {return torsionAtQ;}
182 
186  Real getBinormalCurvatureP() const {return binormalCurvatureAtP;}
190  Real getBinormalCurvatureQ() const {return binormalCurvatureAtQ;}
191 
197  Real getJacobiP() const {return directionalSensitivityQtoP.front()[0];}
203  Real getJacobiQ() const {return directionalSensitivityPtoQ.back()[0];}
204 
207  // Note sign change here -- we calculated this by integrating backwards
208  // so the arc length we used had the opposite sign from the true arc
209  // length parameter.
210  Real getJacobiPDot() const {return -directionalSensitivityQtoP.front()[1];}
213  Real getJacobiQDot() const {return directionalSensitivityPtoQ.back()[1];}
214 
215  // XXX testing
216  Real getJacobiTransP() const {return positionalSensitivityQtoP.front()[0];}
217  Real getJacobiTransQ() const {return positionalSensitivityPtoQ.back()[0];}
218  Real getJacobiTransPDot() const {return -positionalSensitivityQtoP.front()[1];}
219  Real getJacobiTransQDot() const {return positionalSensitivityPtoQ.back()[1];}
220 
223  void clear() {
224  arcLengths.clear();
225  frenetFrames.clear();
226  directionalSensitivityPtoQ.clear();
227  directionalSensitivityQtoP.clear();
228  positionalSensitivityPtoQ.clear();
229  positionalSensitivityQtoP.clear();
230  curvature.clear();
231  torsionAtP = torsionAtQ = NaN;
232  binormalCurvatureAtP = binormalCurvatureAtQ = NaN;
233  convexFlag = shortestFlag = false;
234  initialStepSizeHint = achievedAccuracy = NaN;
235  }
236 
237  void setIsConvex(bool isConvex) {convexFlag = isConvex;}
238  void setIsShortest(bool isShortest) {shortestFlag = isShortest;}
239  void setInitialStepSizeHint(Real sz) {initialStepSizeHint=sz;}
240  void setAchievedAccuracy(Real acc) {achievedAccuracy=acc;}
241 
242  bool isConvex() const {return convexFlag;}
243  bool isShortest() const {return shortestFlag;}
244  Real getInitialStepSizeHint() const {return initialStepSizeHint;}
245  Real getAchievedAccuracy() const {return achievedAccuracy;}
246 
247  void dump(std::ostream& o) const;
248 
249 private:
250  // All these arrays are the same length when the geodesic is complete.
251  Array_<Real> arcLengths; // arc length coord corresponding to point
252  Array_<Transform> frenetFrames; // see above for more info
253  Array_<Vec2> directionalSensitivityPtoQ; // jQ and jQdot
254  Array_<Vec2> directionalSensitivityQtoP; // jP and -jPdot
255  Array_<Vec2> positionalSensitivityPtoQ; // jtQ and jtQdot
256  Array_<Vec2> positionalSensitivityQtoP; // jtP and -jtPdot
257  Array_<Real> curvature; // normal curvature kappa in tangent direction
258  // These are only calculated at the end points.
259  Real torsionAtP, torsionAtQ; // torsion tau (only at ends)
260  Real binormalCurvatureAtP, binormalCurvatureAtQ;
261 
262  // This flag is set true if curvature[i]>=0 for all i.
263  bool convexFlag; // is this geodesic over a convex surface?
264 
265  bool shortestFlag; // XXX is this geodesic the shortest one of the surface?
266  Real initialStepSizeHint; // the initial step size to be tried when integrating this geodesic
267  Real achievedAccuracy; // the accuracy to which this geodesic curve has been calculated
268 };
269 
270 
275 public:
276  GeodesicDecorator(const Geodesic& geod, const Vec3& color) :
277  m_geod(geod), m_color(color) { }
278 
279  virtual void generateDecorations(const State& state,
280  Array_<DecorativeGeometry>& geometry) {
281 // m_system.realize(state, Stage::Position);
282 
283  // draw connected line segments from pts
284  const Array_<Transform>& Kfs = m_geod.getFrenetFrames();
285  Vec3 prevPt;
286  for (int i = 0; i < (int) Kfs.size(); ++i) {
287  Vec3 cur = Kfs[i].p();
288  if (i > 0) {
289  geometry.push_back(
290  DecorativeLine(prevPt, cur)
291  .setColor(m_color)
292  .setLineThickness(3));
293  }
294  prevPt = cur;
295 
296  geometry.push_back(DecorativeFrame(Real(.2)).setTransform(Kfs[i]));
297  }
298  }
299 
300 private:
301  const Geodesic& m_geod;
302  const Vec3& m_color;
303 };
304 
305 
306 
307 
312  // XXX stub
313 };
314 
315 
316 } // namespace SimTK
317 
318 #endif // SimTK_SIMMATH_GEODESIC_H_