Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/parenting/src/curve.cc @ 3327

Last change on this file since 3327 was 3327, checked in by bensch, 19 years ago

orxonox/branches/parenting: added Class UPointCurve. It is so Bad, I can't even believe it myself… you can see the behaviour of this curve in this revision. have fun

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