Allolib  1.0
C++ Components For Interactive Multimedia
al_Curve.hpp
1 #ifndef INCLUDE_AL_CURVE_HPP
2 #define INCLUDE_AL_CURVE_HPP
3 
4 /* Allocore --
5  Multimedia / virtual environment application class library
6 
7  Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
8  Copyright (C) 2012. The Regents of the University of California.
9  All rights reserved.
10 
11  Redistribution and use in source and binary forms, with or without
12  modification, are permitted provided that the following conditions are met:
13 
14  Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16 
17  Redistributions in binary form must reproduce the above copyright
18  notice, this list of conditions and the following disclaimer in the
19  documentation and/or other materials provided with the distribution.
20 
21  Neither the name of the University of California nor the names of its
22  contributors may be used to endorse or promote products derived from
23  this software without specific prior written permission.
24 
25  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  POSSIBILITY OF SUCH DAMAGE.
36 
37 
38  File description:
39  Utilities for computing features of curves
40 
41  File author(s):
42  Lance Putnam, 2012, putnam.lance@gmail.com
43 */
44 
45 namespace al {
46 
48 template <class V2>
49 void frenet(const V2& d1, V2& t, V2& n);
50 
53 template <class V3>
54 void frenet(const V3& d1, const V3& d2, V3& t, V3& n, V3& b);
55 
57 template <class V3>
58 void frenet(const V3& p2, const V3& p1, const V3& p0, V3& t, V3& n, V3& b);
59 
61 
63 
74 template <class Vec3>
75 struct Frenet {
76  Vec3 T;
77  Vec3 N;
78  Vec3 B;
79 
82  Frenet(const Vec3& p2 = Vec3(0, -0.01, 0), const Vec3& p1 = Vec3(0, 0, 0)) {
83  init(p2, p1);
84  }
85 
87  const Vec3& point() const { return mp1; }
88 
90  const Vec3& db() const { return mdb; }
91 
93  const Vec3& df() const { return mdf; }
94 
96  Vec3 d2() const { return mdf - mdb; }
97 
99  void operator()(const Vec3& p0) { next<1, 1, 1, 1, 1>(p0); }
100 
102 
107  template <bool NormalizeT, bool NormalizeN, bool NormalizeB, bool ComputeN,
108  bool ComputeB>
109  void next(const Vec3& p0) {
110  mdb = mdf; // bwd diff is previous fwd diff
111  mdf = p0 - mp1; // compute new fwd diff
112  mp1 = p0; // store previous
113 
114  // Consecutive points equal? If so, use previous frame...
115  // if(mdb == Vec3(0) || mdf == Vec3(0)) return;
116 
117  T = mdb + mdf; // central diff
118  // (really half this, but we only need eigenvector)
119  if (NormalizeT) T.normalize();
120 
121  // Colinear? If so, use previous binormal and normal...
122  /*if(angle(mdf, mdb) < 0.001){
123  //printf("colinear\n");
124  return;
125  }*/
126 
127  if (ComputeB || ComputeN) {
128  B = cross(mdb, mdf);
129  // B = cross(T, mdf - mdb); // formally, we use 2nd difference
130  }
131 
132  if (ComputeN) {
133  N = cross(B, T);
134  if (NormalizeN) N.normalize();
135  }
136 
137  if (NormalizeB) B.normalize();
138  }
139 
141  void init(const Vec3& p2, const Vec3& p1) {
142  mdf = p1 - p2;
143  mp1 = p1;
144  }
145 
146  // /// Get curvature one back back from previous input point
147  // value_type curvature() const {
148  // Vec3 d1 = (mdf + mdb) * 0.5;
149  // value_type d1MagSqr = d1.magSqr();
150  // return sqrt(cross(d1, md2).magSqr() / (d1MagSqr*d1MagSqr*d1MagSqr));
151  // }
152 
153  protected:
154  Vec3 mp1; // Previously input point
155  Vec3 mdb; // Backward first difference
156  Vec3 mdf; // Forward first difference
157 };
158 
159 // Implementation
160 
161 template <class V2>
162 inline void frenet(const V2& d1, V2& t, V2& n) {
163  t = d1;
164  t.normalize();
165  // normal according to right-hand rule
166  n[0] = -t[1];
167  n[1] = t[0];
168 }
169 
170 template <class V3>
171 inline void frenet(const V3& d1, const V3& d2, V3& t, V3& n, V3& b) {
172  b = cross(d2, d1);
173  n = cross(d1, b);
174  t = d1;
175  t.normalize();
176  b.normalize();
177  n.normalize();
178 }
179 
180 template <class V3>
181 inline void frenet(const V3& p2, const V3& p1, const V3& p0, V3& t, V3& n,
182  V3& b) {
183  V3 d1 = (p0 - p2); // 1st (central) difference (scaled by 2)
184  V3 d2 = (p0 - p1 * 2. + p2); // 2nd difference
185  frenet(d1, d2, t, n, b);
186 }
187 
188 //
190 // template <class T, template <class> class NVec>
191 // T curvature(const NVec<T>& a, const NVec<T>& b, const NVec<T>& c);
192 //
193 // template <class T, template <class> class V>
194 // T curvature(const V<T>& a, const V<T>& b, const V<T>& c){
195 //
196 // V<T> d1b = b-a; // first backward difference
197 // V<T> d1f = c-b; // first forward difference
198 // V<T> d1 = (d1f+d1b) * 0.5; // first mid difference
199 //
200 // V<T> d2 = d1f - d1b; // second difference
201 //
202 // T d1n = d1.norm();
203 //
204 // return (d1.cross(d2)).norm() / (d1n*d1n*d1n);
205 //}
206 
207 } // namespace al
208 #endif
Definition: al_App.hpp:23
void frenet(const V2 &d1, V2 &t, V2 &n)
Compute Frenet frame (tangent, normal) from 1st difference.
Definition: al_Curve.hpp:162
void cross(Vec< 3, T > &r, const Vec< 3, T > &a, const Vec< 3, T > &b)
Sets r to cross product, a x b.
Definition: al_Vec.hpp:574
Frenet frame generator.
Definition: al_Curve.hpp:75
Vec3 T
Tangent vector of current frame.
Definition: al_Curve.hpp:76
Frenet(const Vec3 &p2=Vec3(0, -0.01, 0), const Vec3 &p1=Vec3(0, 0, 0))
Definition: al_Curve.hpp:82
Vec3 B
Binormal vector of current frame.
Definition: al_Curve.hpp:78
void next(const Vec3 &p0)
Compute Frenet frame one point back from input point.
Definition: al_Curve.hpp:109
const Vec3 & df() const
Get forward first difference.
Definition: al_Curve.hpp:93
Vec3 N
Normal vector of current frame.
Definition: al_Curve.hpp:77
void operator()(const Vec3 &p0)
Compute Frenet frame one point back from input point.
Definition: al_Curve.hpp:99
void init(const Vec3 &p2, const Vec3 &p1)
(Re)initialize with previous two points
Definition: al_Curve.hpp:141
Vec3 d2() const
Get (central) second difference.
Definition: al_Curve.hpp:96
const Vec3 & db() const
Get backward first difference.
Definition: al_Curve.hpp:90
const Vec3 & point() const
Get point one ahead of currently stored frame.
Definition: al_Curve.hpp:87