Changeset 3365 in orxonox.OLD for orxonox/trunk/src/curve.cc
- Timestamp:
- Jan 7, 2005, 1:14:33 AM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
orxonox/trunk/src/curve.cc
r3217 r3365 11 11 ### File Specific: 12 12 main-programmer: Benjamin Grauer 13 co-programmer: ... 13 co-programmer: Patrick Boenzli 14 15 ADD: Patrick Boenzli B-Spline 16 14 17 15 18 TODO: 16 19 local-Time implementation 17 closed Bezier Curve18 20 NURBS 19 21 … … 21 23 22 24 #include "curve.h" 23 24 25 #include "matrix.h" 26 #include "debug.h" 27 28 #include <math.h> 29 #include <stdio.h> 25 30 26 31 /** … … 37 42 currentNode->next = 0; // not sure if this really points to NULL!! 38 43 currentNode->number = (++nodeCount); 44 this->rebuild(); 39 45 return; 40 46 } 41 47 48 /** 49 \brief Finds a Node by its Number, and returns its Position 50 \param nodeToFind the n'th node in the List of nodes 51 \returns A Vector to the Position of the Node. 52 */ 53 Vector Curve::getNode(unsigned int nodeToFind) 54 { 55 if (nodeToFind > this->nodeCount) 56 return Vector(0,0,0); 57 PathNode* tmpNode = this->firstNode; 58 for (int i = 1; i < nodeToFind; i++) 59 tmpNode = tmpNode->next; 60 return tmpNode->position; 61 } 62 63 /////////////////////////////////// 64 /// Bezier Curve ////////////////// 65 /////////////////////////////////// 42 66 43 67 /** … … 45 69 */ 46 70 BezierCurve::BezierCurve (void) 71 { 72 this->derivation = 0; 73 dirCurve = new BezierCurve(1); 74 this->init(); 75 } 76 77 /** 78 \brief Creates a new BezierCurve-Derivation-Curve 79 */ 80 BezierCurve::BezierCurve (int derivation) 81 { 82 this->derivation = derivation; 83 dirCurve=NULL; 84 this->init(); 85 } 86 87 /** 88 \brief Deletes a BezierCurve. 89 90 It does this by freeing all the space taken over from the nodes 91 */ 92 BezierCurve::~BezierCurve(void) 93 { 94 PathNode* tmpNode; 95 currentNode = firstNode; 96 while (tmpNode != 0) 97 { 98 tmpNode = currentNode; 99 currentNode = currentNode->next; 100 delete tmpNode; 101 } 102 if (dirCurve) 103 delete dirCurve; 104 } 105 106 /** 107 \brief Initializes a BezierCurve 108 */ 109 void BezierCurve::init(void) 47 110 { 48 111 nodeCount = 0; … … 58 121 59 122 /** 60 \brief Deletes a BezierCurve. 123 \brief Rebuilds a Curve 124 */ 125 void BezierCurve::rebuild(void) 126 { 127 PathNode* tmpNode = firstNode; 128 129 // rebuilding the Curve itself 130 float k=0; 131 float n = nodeCount -1; 132 float binCoef = 1; 133 while(tmpNode) 134 { 135 tmpNode->factor = binCoef; 136 if (tmpNode =tmpNode->next) 137 { 138 binCoef *=(n-k)/(k+1); 139 ++k; 140 } 141 } 142 143 // rebuilding the Derivation curve 144 if(this->derivation == 0) 145 { 146 tmpNode = firstNode; 147 delete dirCurve; 148 dirCurve = new BezierCurve(1); 149 while(tmpNode->next) 150 { 151 Vector tmpVector = (tmpNode->next->position)- (tmpNode->position); 152 tmpVector.x*=(float)nodeCount; 153 tmpVector.y*=(float)nodeCount; 154 tmpVector.z*=(float)nodeCount; 155 tmpVector.normalize(); 156 this->dirCurve->addNode(tmpVector); 157 tmpNode = tmpNode->next; 158 } 159 } 160 } 161 162 /** 163 \brief calculates the Position on the curve 164 \param t The position on the Curve (0<=t<=1) 165 \return the Position on the Path 166 */ 167 Vector BezierCurve::calcPos(float t) 168 { 169 Vector ret = Vector(0.0,0.0,0.0); 170 if (this->nodeCount >= 3) 171 { 172 PathNode* tmpNode = this->firstNode; 173 double factor = pow(1.0-t,nodeCount-1); 174 while(tmpNode) 175 { 176 ret.x += tmpNode->factor * factor * tmpNode->position.x; 177 ret.y += tmpNode->factor * factor * tmpNode->position.y; 178 ret.z += tmpNode->factor * factor * tmpNode->position.z; 179 factor *= t/(1.0-t); // same as pow but much faster. 180 181 tmpNode = tmpNode->next; 182 } 183 } 184 else if (nodeCount == 2) 185 { 186 ret = this->firstNode->position *(1.0-t); 187 ret = ret + this->firstNode->next->position * t; 188 } 189 else if (nodeCount == 1) 190 ret = this->firstNode->position; 191 return ret; 192 } 193 194 /** 195 \brief Calulates the direction of the Curve at time t. 196 \param The time at which to evaluate the curve. 197 \returns The vvaluated Vector. 198 */ 199 Vector BezierCurve::calcDir (float t) 200 { 201 return dirCurve->calcPos(t); 202 } 203 204 /** 205 \brief Calculates the Quaternion needed for our rotations 206 \param t The time at which to evaluate the cuve. 207 \returns The evaluated Quaternion. 208 */ 209 Quaternion BezierCurve::calcQuat (float t) 210 { 211 return Quaternion (calcDir(t), Vector(0,0,1)); 212 } 213 214 215 /** 216 \brief returns the Position of the point calculated on the Curve 217 \return a Vector to the calculated position 218 */ 219 Vector BezierCurve::getPos(void) const 220 { 221 return curvePoint; 222 } 223 224 225 226 /////////////////////////////////// 227 //// Uniform Point curve ///////// 228 /////////////////////////////////// 229 /** 230 \brief Creates a new UPointCurve 231 */ 232 UPointCurve::UPointCurve (void) 233 { 234 this->derivation = 0; 235 this->init(); 236 } 237 238 /** 239 \brief Creates a new UPointCurve-Derivation-Curve of deriavation'th degree 240 */ 241 UPointCurve::UPointCurve (int derivation) 242 { 243 this->derivation = derivation; 244 dirCurve=NULL; 245 this->init(); 246 } 247 248 /** 249 \brief Deletes a UPointCurve. 61 250 62 251 It does this by freeing all the space taken over from the nodes 63 252 */ 64 BezierCurve::~BezierCurve(void)253 UPointCurve::~UPointCurve(void) 65 254 { 66 255 PathNode* tmpNode; … … 72 261 delete tmpNode; 73 262 } 263 if (dirCurve) 264 delete dirCurve; 265 } 266 267 /** 268 \brief Initializes a UPointCurve 269 */ 270 void UPointCurve::init(void) 271 { 272 nodeCount = 0; 273 firstNode = new PathNode; 274 currentNode = firstNode; 275 276 firstNode->position = Vector (.0, .0, .0); 277 firstNode->number = 0; 278 firstNode->next = 0; // not sure if this really points to NULL!! 279 280 return; 281 } 282 283 /** 284 \brief Rebuilds a UPointCurve 285 286 \todo very bad algorithm 287 */ 288 void UPointCurve::rebuild(void) 289 { 290 // rebuilding the Curve itself 291 PathNode* tmpNode = this->firstNode; 292 int i=0; 293 Matrix xTmpMat = Matrix(this->nodeCount, this->nodeCount); 294 Matrix yTmpMat = Matrix(this->nodeCount, this->nodeCount); 295 Matrix zTmpMat = Matrix(this->nodeCount, this->nodeCount); 296 Matrix xValMat = Matrix(this->nodeCount, 3); 297 Matrix yValMat = Matrix(this->nodeCount, 3); 298 Matrix zValMat = Matrix(this->nodeCount, 3); 299 while(tmpNode) 300 { 301 Vector fac = Vector(1,1,1); 302 for (int j = 0; j < this->nodeCount; j++) 303 { 304 xTmpMat(i,j) = fac.x; fac.x *= (float)i/(float)this->nodeCount;//tmpNode->position.x; 305 yTmpMat(i,j) = fac.y; fac.y *= (float)i/(float)this->nodeCount;//tmpNode->position.y; 306 zTmpMat(i,j) = fac.z; fac.z *= (float)i/(float)this->nodeCount;//tmpNode->position.z; 307 } 308 xValMat(i,0) = tmpNode->position.x; 309 yValMat(i,0) = tmpNode->position.y; 310 zValMat(i,0) = tmpNode->position.z; 311 ++i; 312 tmpNode = tmpNode->next; 313 } 314 tmpNode = this->firstNode; 315 xValMat = xTmpMat.Inv() *= xValMat; 316 yValMat = yTmpMat.Inv() *= yValMat; 317 zValMat = zTmpMat.Inv() *= zValMat; 318 i = 0; 319 while(tmpNode) 320 { 321 tmpNode->vFactor.x = xValMat(i,0); 322 tmpNode->vFactor.y = yValMat(i,0); 323 tmpNode->vFactor.z = zValMat(i,0); 324 325 i++; 326 tmpNode = tmpNode->next; 327 } 74 328 } 75 329 … … 79 333 \return the Position on the Path 80 334 */ 81 Vector BezierCurve::calcPos(float t) 82 { 83 if (nodeCount <=4) 84 { 85 // if (verbose >= 1) 86 // printf ("Please define at least 4 nodes, until now you have only defined %i.\n", nodeCount); 87 return Vector(0,0,0); 88 } 335 Vector UPointCurve::calcPos(float t) 336 { 89 337 PathNode* tmpNode = firstNode; 90 91 338 Vector ret = Vector(0.0,0.0,0.0); 92 double factor; 93 int k=0; 94 while(tmpNode!=0) 95 { 96 k++; 97 factor = ncr (nodeCount, k); 98 99 for (int j=0; j<nodeCount-k; j++) 100 factor*=(1-t); 101 for (int j=0; j<k; j++) 102 factor*=t; 103 ret.x += factor * tmpNode->position.x; 104 ret.y += factor * tmpNode->position.y; 105 ret.z += factor * tmpNode->position.z; 106 339 float factor = 1.0; 340 while(tmpNode) 341 { 342 ret.x += tmpNode->vFactor.x * factor; 343 ret.y += tmpNode->vFactor.y * factor; 344 ret.z += tmpNode->vFactor.z * factor; 345 factor *= t; 346 107 347 tmpNode = tmpNode->next; 108 109 348 } 110 349 return ret; … … 116 355 \returns The vvaluated Vector. 117 356 */ 118 Vector BezierCurve::calcDir (float t)357 Vector UPointCurve::calcDir (float t) 119 358 { 120 359 PathNode* tmpNode = firstNode; 121 BezierCurve* tmpCurve = new BezierCurve(); 122 Vector ret; 123 Vector tmpVector; 124 125 while (tmpNode->next != 0) 126 { 127 tmpVector = (tmpNode->next->position)- (tmpNode->position); 128 tmpVector.x*=(float)nodeCount; 129 tmpVector.y*=(float)nodeCount; 130 tmpVector.z*=(float)nodeCount; 131 132 tmpCurve->addNode(tmpVector); 360 Vector ret = Vector(0.0,0.0,0.0); 361 float factor = 1.0/t; 362 int k=0; 363 while(tmpNode) 364 { 365 ret.x += tmpNode->vFactor.x * factor *k; 366 ret.y += tmpNode->vFactor.y * factor *k; 367 ret.z += tmpNode->vFactor.z * factor *k; 368 factor *= t; 369 k++; 133 370 tmpNode = tmpNode->next; 134 371 } 135 ret = tmpCurve->calcPos(t);136 372 ret.normalize(); 137 138 373 return ret; 139 374 } … … 144 379 \returns The evaluated Quaternion. 145 380 */ 146 Quaternion BezierCurve::calcQuat (float t)381 Quaternion UPointCurve::calcQuat (float t) 147 382 { 148 383 return Quaternion (calcDir(t), Vector(0,0,1)); … … 154 389 \return a Vector to the calculated position 155 390 */ 156 Vector BezierCurve::getPos() const391 Vector UPointCurve::getPos(void) const 157 392 { 158 393 return curvePoint; 159 394 } 160 161 /**162 \brief ncr-calculator, did not find an other method163 \todo a c++ variante to do this164 */165 int ncr(int n, int i)166 {167 int ret = 1;168 for (int k=1; k<=n; k++)169 ret*=k;170 for (int k=1; k<=i; k++)171 ret/=k;172 for (int k=1; k<=n-i; k++)173 ret/=k;174 175 return ret;176 }177
Note: See TracChangeset
for help on using the changeset viewer.