1 #ifndef SPLINE_SPLINE_H 2 #define SPLINE_SPLINE_H 11 const Real Third = Real(1.0/3.0);
29 enum InfinityBehavior {
40 virtual void init(
int numKeys);
41 virtual void resize(
int numKeys);
42 virtual void cleanup();
46 virtual bool Read(
File&);
47 virtual bool Write(
File&)
const;
52 inline int getNumKeys()
const {
return (
int)times.size(); }
53 inline int getNumSegments()
const {
return (
int)times.size()-1; }
54 Real& getTime(
int i) {
return times[i]; }
55 const Real& getTime(
int i)
const {
return times[i]; }
57 inline Real beginTime()
const {
return times[0]; }
58 inline Real endTime()
const {
return times[times.size()-1]; }
59 inline Real length()
const {
return endTime() - beginTime(); }
60 inline int isLooping()
const {
return flags & InfinityLoop; }
61 inline void setInfinityBehavior(InfinityBehavior b) { flags = b; }
62 void timeTransform(Real scale, Real offset);
66 inline Real mapSegmentU(
int seg, Real t)
const 68 return (t - times[seg])/(times[seg+1] - times[seg]);
70 Real infinityMap(Real t)
const;
72 std::vector<Real> times;
77 template <
class Po
int>
84 template <
class Po
int>
91 template <
class Po
int>
98 template <
class Po
int>
106 template <
class Key,
class Po
int>
112 void init(
int numKeys);
114 int insertKey(Real time,
int pos=-1);
115 void deleteKey(
int key);
118 inline Key& getKey(
int i) {
return keys[i]; }
119 inline const Key& getKey(
int i)
const {
return keys[i]; }
122 virtual bool Read(
File&);
123 virtual bool Write(
File&)
const;
125 virtual void eval(
int seg, Real u, Point& out)
const = 0;
127 std::vector<Key> keys;
130 template <
class Po
int>
135 inline Point& getPoint(
int i) {
return ParentT::points[i]; }
136 inline const Point& getPoint(
int i)
const {
return ParentT::points[i]; }
137 inline int getNumKeys()
const {
return ParentT::getNumKeys(); }
138 inline int getNumSegments()
const {
return ParentT::getNumSegments(); }
140 virtual void eval(
int seg, Real u, Point& out)
const {
141 out = ParentT::keys[seg] + u*(ParentT::keys[seg+1]-ParentT::keys[seg]);
145 template <
class Po
int>
150 inline Point& getPoint(
int i) {
return ParentT::keys[i].pt; }
151 inline const Point& getPoint(
int i)
const {
return ParentT::keys[i].pt; }
152 inline int getNumKeys()
const {
return ParentT::getNumKeys(); }
153 inline int getNumSegments()
const {
return ParentT::getNumSegments(); }
155 inline Point& getTangentIn(
int i) {
return ParentT::keys[i].tin; }
156 inline const Point& getTangentIn(
int i)
const {
return ParentT::keys[i].tin; }
157 inline Point& getTangentOut(
int i) {
return ParentT::keys[i].tout; }
158 inline const Point& getTangentOut(
int i)
const {
return ParentT::keys[i].tout; }
160 virtual void eval(
int seg, Real u, Point& out)
const {
163 basis.EvalBasis(u, b);
165 out = b[0]*getPoint(seg) + b[1]*getPoint(seg+1) + b[2]*getTangentOut(seg) + b[3]*getTangentIn(seg+1);
169 template <
class Po
int>
177 inline Point& getPoint(
int i) {
return ParentT::keys[i].pt; }
178 inline const Point& getPoint(
int i)
const {
return ParentT::keys[i].pt; }
179 inline int getNumKeys()
const {
return ParentT::getNumKeys(); }
180 inline int getNumSegments()
const {
return ParentT::getNumSegments(); }
182 inline Real& getTension(
int i) {
return ParentT::keys[i].tension; }
183 inline const Real& getTension(
int i)
const {
return ParentT::keys[i].tension; }
187 virtual void eval(
int seg, Real u, Point& out)
const {
188 int a = (seg > 0 ? seg-1 : 0);
189 int d = (seg+2 < ParentT::getNumKeys() ? seg+2 : getNumKeys()-1);
191 const Point& P0 = getPoint(seg);
192 const Point& P1 = getPoint(seg+1);
194 T0 = getTension(seg)*(P1 - getPoint(a));
195 T1 = getTension(seg)*(getPoint(d) - P0);
199 basis.EvalBasis(u, b);
200 out = b[0]*P0 + b[1]*P1 + b[2]*T0 + b[3]*T1;
204 template <
class Po
int>
210 inline Point& getPoint(
int i) {
return ParentT::keys[i].pt; }
211 inline const Point& getPoint(
int i)
const {
return ParentT::keys[i].pt; }
212 inline int getNumKeys()
const {
return ParentT::getNumKeys(); }
213 inline int getNumSegments()
const {
return ParentT::getNumSegments(); }
215 inline Point& getCPIn(
int i) {
return ParentT::keys[i].cpin; }
216 inline Point& getCPOut(
int i) {
return ParentT::keys[i].cpin; }
217 inline const Point& getCPIn(
int i)
const {
return ParentT::keys[i].cpout; }
218 inline const Point& getCPOut(
int i)
const {
return ParentT::keys[i].cpout; }
223 virtual void eval(
int seg, Real u, Point& out)
const {
226 basis.EvalBasis(u, b);
228 out = b[0]*getPoint(seg) + b[1]*getCPOut(seg) + b[2]*getCPIn(seg+1) + b[3]*getPoint(seg+1);
232 template <
class Po
int>
243 inline Point& getPoint(
int i) {
return ParentT::keys[i].pt; }
244 inline const Point& getPoint(
int i)
const {
return ParentT::keys[i].pt; }
245 inline int getNumKeys()
const {
return ParentT::getNumKeys(); }
246 inline int getNumSegments()
const {
return ParentT::getNumSegments(); }
248 inline Real& getTension(
int i) {
return ParentT::keys[i].t; };
249 inline Real& getContinuity(
int i) {
return ParentT::keys[i].c; };
250 inline Real& getBias(
int i) {
return ParentT::keys[i].b; };
251 inline const Real& getTension(
int i)
const {
return ParentT::keys[i].t; };
252 inline const Real& getContinuity(
int i)
const {
return ParentT::keys[i].c; };
253 inline const Real& getBias(
int i)
const {
return ParentT::keys[i].b; };
255 virtual void eval(
int seg, Real u, Point& out)
const {
256 int a = (seg > 0 ? seg-1 : 0);
257 int d = (seg+2 < getNumKeys() ? seg+2 : getNumKeys()-1);
259 const Point& P_1 = getPoint(a);
260 const Point& P0 = getPoint(seg);
261 const Point& P1 = getPoint(seg+1);
262 const Point& P2 = getPoint(d);
265 T0 = outgoingTangent(seg, P_1, P0, P1);
266 T1 = incomingTangent(seg, P0, P1, P2);
270 basis.EvalBasis(u, b);
271 out = b[0]*P0 + b[1]*P1 + b[2]*T0 + b[3]*T1;
274 Point incomingTangent(
int seg,
const Point& P_1,
const Point& P0,
const Point& P1)
const 277 t = getTension(seg); c = getContinuity(seg); b = getBias(seg);
278 return ((1-t)*(1-c)*(1+b)*Half)*(P0 - P_1) + ((1-t)*(1+c)*(1-b)*Half)*(P1 - P0);
281 Point outgoingTangent(
int seg,
const Point& P_1,
const Point& P0,
const Point& P1)
const 284 t = getTension(seg); c = getContinuity(seg); b = getBias(seg);
285 return ((1-t)*(1+c)*(1+b)*Half)*(P0 - P_1) + ((1-t)*(1-c)*(1-b)*Half)*(P1 - P0);
Class declarations for useful 3D math types.
Contains all the definitions in the Math3D package.
Definition: AnyGeometry.h:12
Definition: spline/basis.h:62
Definition: spline/basis.h:86
A cross-platform class for reading/writing binary data.
Definition: File.h:47