1 #ifndef SPLINE_SPLINE_H 2 #define SPLINE_SPLINE_H 11 const Real Third = Real(1.0/3.0);
28 enum InfinityBehavior {
39 virtual void init(
int numKeys);
40 virtual void resize(
int numKeys);
41 virtual void cleanup();
45 virtual bool Read(
File&);
46 virtual bool Write(
File&)
const;
51 inline int getNumKeys()
const {
return (
int)times.size(); }
52 inline int getNumSegments()
const {
return (
int)times.size()-1; }
53 Real& getTime(
int i) {
return times[i]; }
54 const Real& getTime(
int i)
const {
return times[i]; }
56 inline Real beginTime()
const {
return times[0]; }
57 inline Real endTime()
const {
return times[times.size()-1]; }
58 inline Real length()
const {
return endTime() - beginTime(); }
59 inline int isLooping()
const {
return flags & InfinityLoop; }
60 inline void setInfinityBehavior(InfinityBehavior b) { flags = b; }
61 void timeTransform(Real scale, Real offset);
65 inline Real mapSegmentU(
int seg, Real t)
const 67 return (t - times[seg])/(times[seg+1] - times[seg]);
69 Real infinityMap(Real t)
const;
71 std::vector<Real> times;
76 template <
class Po
int>
83 template <
class Po
int>
90 template <
class Po
int>
97 template <
class Po
int>
105 template <
class Key,
class Po
int>
110 void init(
int numKeys);
112 int insertKey(Real time,
int pos=-1);
113 void deleteKey(
int key);
116 inline Key& getKey(
int i) {
return keys[i]; }
117 inline const Key& getKey(
int i)
const {
return keys[i]; }
120 virtual bool Read(
File&);
121 virtual bool Write(
File&)
const;
123 virtual void eval(
int seg, Real u, Point& out)
const = 0;
125 std::vector<Key> keys;
128 template <
class Po
int>
133 inline Point& getPoint(
int i) {
return ParentT::points[i]; }
134 inline const Point& getPoint(
int i)
const {
return ParentT::points[i]; }
135 inline int getNumKeys()
const {
return ParentT::getNumKeys(); }
136 inline int getNumSegments()
const {
return ParentT::getNumSegments(); }
138 virtual void eval(
int seg, Real u, Point& out)
const {
139 out = ParentT::keys[seg] + u*(ParentT::keys[seg+1]-ParentT::keys[seg]);
143 template <
class Po
int>
148 inline Point& getPoint(
int i) {
return ParentT::keys[i].pt; }
149 inline const Point& getPoint(
int i)
const {
return ParentT::keys[i].pt; }
150 inline int getNumKeys()
const {
return ParentT::getNumKeys(); }
151 inline int getNumSegments()
const {
return ParentT::getNumSegments(); }
153 inline Point& getTangentIn(
int i) {
return ParentT::keys[i].tin; }
154 inline const Point& getTangentIn(
int i)
const {
return ParentT::keys[i].tin; }
155 inline Point& getTangentOut(
int i) {
return ParentT::keys[i].tout; }
156 inline const Point& getTangentOut(
int i)
const {
return ParentT::keys[i].tout; }
158 virtual void eval(
int seg, Real u, Point& out)
const {
161 basis.EvalBasis(u, b);
163 out = b[0]*getPoint(seg) + b[1]*getPoint(seg+1) + b[2]*getTangentOut(seg) + b[3]*getTangentIn(seg+1);
167 template <
class Po
int>
175 inline Point& getPoint(
int i) {
return ParentT::keys[i].pt; }
176 inline const Point& getPoint(
int i)
const {
return ParentT::keys[i].pt; }
177 inline int getNumKeys()
const {
return ParentT::getNumKeys(); }
178 inline int getNumSegments()
const {
return ParentT::getNumSegments(); }
180 inline Real& getTension(
int i) {
return ParentT::keys[i].tension; }
181 inline const Real& getTension(
int i)
const {
return ParentT::keys[i].tension; }
185 virtual void eval(
int seg, Real u, Point& out)
const {
186 int a = (seg > 0 ? seg-1 : 0);
187 int d = (seg+2 < ParentT::getNumKeys() ? seg+2 : getNumKeys()-1);
189 const Point& P0 = getPoint(seg);
190 const Point& P1 = getPoint(seg+1);
192 T0 = getTension(seg)*(P1 - getPoint(a));
193 T1 = getTension(seg)*(getPoint(d) - P0);
197 basis.EvalBasis(u, b);
198 out = b[0]*P0 + b[1]*P1 + b[2]*T0 + b[3]*T1;
202 template <
class Po
int>
208 inline Point& getPoint(
int i) {
return ParentT::keys[i].pt; }
209 inline const Point& getPoint(
int i)
const {
return ParentT::keys[i].pt; }
210 inline int getNumKeys()
const {
return ParentT::getNumKeys(); }
211 inline int getNumSegments()
const {
return ParentT::getNumSegments(); }
213 inline Point& getCPIn(
int i) {
return ParentT::keys[i].cpin; }
214 inline Point& getCPOut(
int i) {
return ParentT::keys[i].cpin; }
215 inline const Point& getCPIn(
int i)
const {
return ParentT::keys[i].cpout; }
216 inline const Point& getCPOut(
int i)
const {
return ParentT::keys[i].cpout; }
221 virtual void eval(
int seg, Real u, Point& out)
const {
224 basis.EvalBasis(u, b);
226 out = b[0]*getPoint(seg) + b[1]*getCPOut(seg) + b[2]*getCPIn(seg+1) + b[3]*getPoint(seg+1);
230 template <
class Po
int>
241 inline Point& getPoint(
int i) {
return ParentT::keys[i].pt; }
242 inline const Point& getPoint(
int i)
const {
return ParentT::keys[i].pt; }
243 inline int getNumKeys()
const {
return ParentT::getNumKeys(); }
244 inline int getNumSegments()
const {
return ParentT::getNumSegments(); }
246 inline Real& getTension(
int i) {
return ParentT::keys[i].t; };
247 inline Real& getContinuity(
int i) {
return ParentT::keys[i].c; };
248 inline Real& getBias(
int i) {
return ParentT::keys[i].b; };
249 inline const Real& getTension(
int i)
const {
return ParentT::keys[i].t; };
250 inline const Real& getContinuity(
int i)
const {
return ParentT::keys[i].c; };
251 inline const Real& getBias(
int i)
const {
return ParentT::keys[i].b; };
253 virtual void eval(
int seg, Real u, Point& out)
const {
254 int a = (seg > 0 ? seg-1 : 0);
255 int d = (seg+2 < getNumKeys() ? seg+2 : getNumKeys()-1);
257 const Point& P_1 = getPoint(a);
258 const Point& P0 = getPoint(seg);
259 const Point& P1 = getPoint(seg+1);
260 const Point& P2 = getPoint(d);
263 T0 = outgoingTangent(seg, P_1, P0, P1);
264 T1 = incomingTangent(seg, P0, P1, P2);
268 basis.EvalBasis(u, b);
269 out = b[0]*P0 + b[1]*P1 + b[2]*T0 + b[3]*T1;
272 Point incomingTangent(
int seg,
const Point& P_1,
const Point& P0,
const Point& P1)
const 275 t = getTension(seg); c = getContinuity(seg); b = getBias(seg);
276 return ((1-t)*(1-c)*(1+b)*Half)*(P0 - P_1) + ((1-t)*(1+c)*(1-b)*Half)*(P1 - P0);
279 Point outgoingTangent(
int seg,
const Point& P_1,
const Point& P0,
const Point& P1)
const 282 t = getTension(seg); c = getContinuity(seg); b = getBias(seg);
283 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:13
Definition: spline/basis.h:62
Definition: spline/basis.h:86
A cross-platform class for reading/writing binary data.
Definition: File.h:47