Homepage | Demos | Overview | Downloads | Tutorials | Reference | Credits |
00001 //-*-c++-*- 00002 /*======================================================================== 00003 spline.h : Implementation of Uniform and Non-Uniform Hermite Splines 00004 ------------------------------------------------------------------------ 00005 Copyright (C) 1999-2002 James R. Bruce 00006 School of Computer Science, Carnegie Mellon University 00007 ------------------------------------------------------------------------ 00008 This software is distributed under the GNU General Public License, 00009 version 2. If you do not have a copy of this licence, visit 00010 www.gnu.org, or write: Free Software Foundation, 59 Temple Place, 00011 Suite 330 Boston, MA 02111-1307 USA. This program is distributed 00012 in the hope that it will be useful, but WITHOUT ANY WARRANTY, 00013 including MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00014 ========================================================================*/ 00015 00016 #ifndef __SPLINE_H__ 00017 #define __SPLINE_H__ 00018 00019 #define HSPLINE HermiteSplineSegment<point,fnum> 00020 #define NUHSPLINE NonUniformHermiteSplineSegment<point,fnum> 00021 00022 #define HSPLINE_TEM template <class point,class fnum> 00023 #define NUHSPLINE_TEM template <class point,class fnum> 00024 00025 // #define TSPLINE HermiteSplineSegment<fnum,fnum> 00026 // #define CRSPLINE CatmullRomSpline<point,fnum> 00027 // #define CRSPLINE_TEM template <class point,class fnum> 00028 00029 #define EPS 1E-6 00030 00031 // #define DEBUG 00032 00033 HSPLINE_TEM 00034 class HermiteSplineSegment{ 00035 public: 00036 HermiteSplineSegment() : a(),b(),c(),d() {} 00037 point a,b,c,d; 00038 public: 00039 void create(point x1,point x2,point dx1,point dx2); 00040 void create(point *pts,int num,int i); 00041 point eval(fnum u); 00042 point eval_deriv(fnum u); 00043 }; 00044 00045 NUHSPLINE_TEM 00046 class NonUniformHermiteSplineSegment{ 00047 public: 00048 NonUniformHermiteSplineSegment() : a(),b(),c(),d(),t() {} 00049 point a,b,c,d; 00050 fnum t; 00051 public: 00052 void create(point x0,point x1,point dx0,point dx1,fnum t1); 00053 void create(point *pts,double t1,int num,int i); 00054 point eval(fnum u); 00055 point eval_deriv(fnum u); 00056 }; 00057 00058 /* 00059 template <class point,class fnum> 00060 class CatmullRomSpline{ 00061 typedef HermiteSplineSegment<point,fnum> segment; 00062 segment *seg; 00063 int num_segs,max; 00064 double 00065 public: 00066 CatmullRomSpline() 00067 {seg=NULL; num_segs=max=0;} 00068 00069 bool allocate(int num); 00070 int find_segment(fnum t); 00071 00072 // void create(point *pts,num *time,point dx1,point dx2,int num); 00073 bool create(point *pts,fnum *time,int num); 00074 bool create_loop(point *pts,fnum *time,int num); 00075 point eval(fnum t); 00076 point eval_deriv(fnum t); 00077 }; 00078 */ 00079 00080 00081 //==== Hermite Spline Segment Implementation ====// 00082 00083 HSPLINE_TEM 00084 void HSPLINE::create(point x1,point x2,point dx1,point dx2) 00085 { 00086 // a = (x1 * 2) + (x2 * -2) + (dx1 * 1) + (dx2 * 1); 00087 // b = (x1 * -3) + (x2 * 3) + (dx1 * -2) + (dx2 * -1); 00088 a = (x1 - x2)*2 + dx1 + dx2; 00089 b = (x2 - x1)*3 - dx1*2 - dx2; 00090 c = dx1; 00091 d = x1; 00092 } 00093 00094 HSPLINE_TEM 00095 void HSPLINE::create(point *pts,int num,int i) 00096 { 00097 point x1,x2,dx1,dx2; 00098 00099 x1 = pts[(i + 1) % num]; 00100 x2 = pts[(i + 2) % num]; 00101 dx1 = x2 - pts[(i + 0) % num]; 00102 dx2 = pts[(i + 3) % num] - x1; 00103 00104 create(x1,x2,dx1,dx2); 00105 } 00106 00107 HSPLINE_TEM 00108 point HSPLINE::eval(fnum u) 00109 { 00110 fnum u2,u3; 00111 point p; 00112 00113 u2 = u*u; 00114 u3 = u*u*u; 00115 00116 p = a*u3 + b*u2 + c*u + d; 00117 00118 return(p); 00119 } 00120 00121 HSPLINE_TEM 00122 point HSPLINE::eval_deriv(fnum u) 00123 { 00124 fnum u2; 00125 point p; 00126 00127 u2 = u*u; 00128 00129 p = a*(3*u2) + b*(2*u) + c; 00130 00131 return(p); 00132 } 00133 00134 00135 //==== Non-Uniform Hermite Spline Segment Implementation ====// 00136 00137 NUHSPLINE_TEM 00138 void NUHSPLINE::create(point x0,point x1,point dx0,point dx1,fnum t1) 00139 { 00140 t = t1; 00141 d = x0; 00142 c = dx0; 00143 // b = ((x1-c*t1-d)*3 - dx1*t1) / (t1*t1); 00144 // a = (dx1 - b*t1*2 - c) / (t1*t1*3); 00145 b = ((x1 - x0)*3 - dx0*(t*2) - dx1*t) / (t*t); 00146 a = (dx1 - dx0 - b*(t*2)) / (3*t*t); 00147 00148 #ifdef DEBUG 00149 /* point tx0,tx1,tdx0,tdx1; 00150 00151 tx0 = eval(0.0) - x0; 00152 tx1 = eval(t1) - x1; 00153 tdx0 = eval_deriv(0.0) - dx0; 00154 tdx1 = eval_deriv(t1) - dx1; 00155 00156 / * 00157 printf("Error: %f\n", 00158 tx0.sqlength() + tx1.sqlength() + 00159 tdx0.sqlength() + tdx1.sqlength()); 00160 * / 00161 00162 printf("Error: x0(%f,%f,%f) x1(%f,%f,%f) dx0(%f,%f,%f) dx1(%f,%f,%f)\n", 00163 tx0.x, tx0.y, tx0.z, 00164 tx1.x, tx1.y, tx1.z, 00165 tdx0.x, tdx0.y, tdx0.z, 00166 tdx1.x, tdx1.y, tdx1.z);*/ 00167 #endif 00168 } 00169 00170 NUHSPLINE_TEM 00171 void NUHSPLINE::create(point *pts,double t1,int num,int i) 00172 // Not 100% sure this is a logical thing to calculate 00173 { 00174 point x0,x1,dx0,dx1; 00175 00176 x0 = pts[(i + 1) % num]; 00177 x1 = pts[(i + 2) % num]; 00178 dx0 = (x1 - pts[(i + 0) % num]) / (2*t1); 00179 dx1 = (pts[(i + 3) % num] - x0) / (2*t1); 00180 00181 create(x0,x1,dx0,dx1,t1); 00182 } 00183 00184 NUHSPLINE_TEM 00185 point NUHSPLINE::eval(fnum u) 00186 { 00187 fnum u2,u3; 00188 point p; 00189 00190 u2 = u*u; 00191 u3 = u*u*u; 00192 00193 p = a*u3 + b*u2 + c*u + d; 00194 00195 return(p); 00196 } 00197 00198 NUHSPLINE_TEM 00199 point NUHSPLINE::eval_deriv(fnum u) 00200 { 00201 fnum u2; 00202 point p; 00203 00204 u2 = u*u; 00205 00206 p = a*(3*u2) + b*(2*u) + c; 00207 00208 return(p); 00209 } 00210 00211 //==== Catmull-Rom Spline Implementation ====// 00212 00213 /* 00214 HSPLINE_TEM 00215 void makeSpline(HSPLINE *seg,const point *pts,int num) 00216 { 00217 int i; 00218 00219 for(i=0; i<num-3; i++){ 00220 seg[i].create(pts[i+1],pts[i+2],pts[i+2] - pts[i+0],pts[i+3] - pts[i+1]); 00221 } 00222 } 00223 00224 HSPLINE_TEM 00225 point evalSpline(HSPLINE *seg,int num,double t) 00226 { 00227 int s; 00228 00229 if(t >= num) t = num - EPS; 00230 if(t <= 0.0) t = 0.0; 00231 s = (int)t; 00232 00233 return(seg[s].eval(t - s)); 00234 } 00235 00236 HSPLINE_TEM 00237 void makeSpline(HSPLINE *seg,TSPLINE *tseg,const point *pts,fnum time,int num) 00238 { 00239 int i; 00240 00241 for(i=0; i<num-3; i++){ 00242 tseg[i].create(time[i+1],time[i+2],time[i+2] - time[i+0],time[i+3] - time[i+1]); 00243 seg[i].create(pts[i+1],pts[i+2],pts[i+2] - pts[i+0],pts[i+3] - pts[i+1]); 00244 } 00245 } 00246 00247 HSPLINE_TEM 00248 point evalSpline(HSPLINE *seg,TSPLINE *tseg,int num,double t) 00249 { 00250 int s; 00251 00252 // find time to evaluate point spline 00253 if(t >= num) t = num - EPS; 00254 if(t <= 0.0) t = 0.0; 00255 s = (int)t; 00256 t = tseg[s].eval(t - s); 00257 00258 // evaluate it 00259 s = (int)t; 00260 return(seg[s].eval(t - s)); 00261 } 00262 */ 00263 00264 /* 00265 CRSPLINE_TEM 00266 bool CRSPLINE::allocate(int num) 00267 { 00268 current = 0; 00269 00270 if(num <= max){ 00271 num_segs = num; 00272 return(true); 00273 } 00274 00275 if(seg) delete(seg); 00276 seg = new segment[num]; 00277 00278 if(seg){ 00279 max = num_segs = num; 00280 return(true); 00281 }else{ 00282 max = num_segs = 0; 00283 return(false); 00284 } 00285 } 00286 00287 CRSPLINE_TEM 00288 bool CRSPLINE::create(point *pts,fnum *ntime,int num) 00289 { 00290 if(!allocate(num)) return(false); 00291 00292 // TODO 00293 00294 return(false); 00295 } 00296 00297 CRSPLINE_TEM 00298 bool CRSPLINE::create_loop(point *pts,fnum *time,int num) 00299 { 00300 point ldx,dx; 00301 fnum sum,t; 00302 int i; 00303 00304 if(!allocate(num)) return(false); 00305 00306 ldx = (pts[1] - pts[num-1]) / time[0]; 00307 sum = 0.0; 00308 00309 for(i=0; i<num_segs; i++){ 00310 dx = (pts[(i+2)%num_segs] - pts[i]) / time[(i+1)%num_segs]; 00311 t = time[i]; 00312 00313 // printf("i = %d\n",i); fflush(stdout); 00314 seg[i].create(pts[i],pts[(i+1)%num_segs],ldx*t,dx*t,sum,t); 00315 00316 sum += t; 00317 ldx = dx; 00318 } 00319 00320 return(true); 00321 } 00322 00323 CRSPLINE_TEM 00324 int CRSPLINE::find_segment(fnum t) 00325 { 00326 fnum d; 00327 int i; 00328 00329 d = t - seg[current].start; 00330 if(d>=0 && d<=seg[current].time) return(current); 00331 00332 for(i=0; i<num_segs; i++){ 00333 d = t - seg[i].start; 00334 if(d>=0 && d<=seg[i].time) return(current = i); 00335 } 00336 00337 return(current = num_segs - 1); 00338 } 00339 00340 CRSPLINE_TEM 00341 point CRSPLINE::eval(fnum t) 00342 { 00343 int i; 00344 i = find_segment(t); 00345 return(seg[i].eval(t)); 00346 } 00347 00348 CRSPLINE_TEM 00349 point CRSPLINE::eval_deriv(fnum t) 00350 { 00351 int i; 00352 i = find_segment(t); 00353 return(seg[i].eval_deriv(t)); 00354 } 00355 */ 00356 00357 /*! @file 00358 * @brief Performs calculations regarding splines for path execution 00359 * @author James R. Bruce (Creator) 00360 * 00361 * @verbatim 00362 ======================================================================== 00363 spline.h : Implementation of Uniform and Non-Uniform Hermite Splines 00364 ------------------------------------------------------------------------ 00365 Copyright (C) 1999-2002 James R. Bruce 00366 School of Computer Science, Carnegie Mellon University 00367 ------------------------------------------------------------------------ 00368 This software is distributed under the GNU General Public License, 00369 version 2. If you do not have a copy of this licence, visit 00370 www.gnu.org, or write: Free Software Foundation, 59 Temple Place, 00371 Suite 330 Boston, MA 02111-1307 USA. This program is distributed 00372 in the hope that it will be useful, but WITHOUT ANY WARRANTY, 00373 including MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00374 ======================================================================== 00375 * @endverbatim 00376 * 00377 * $Author: ejt $ 00378 * $Name: tekkotsu-1_4_1 $ 00379 * $Revision: 1.4 $ 00380 * $State: Exp $ 00381 * $Date: 2003/01/23 18:14:04 $ 00382 */ 00383 00384 #endif 00385 // __SPLINE_H__ 00386
Tekkotsu v1.4 |
Generated Sat Jul 19 00:06:31 2003 by Doxygen 1.3.2 |