Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 3365 in orxonox.OLD for orxonox/trunk/src/curve.cc


Ignore:
Timestamp:
Jan 7, 2005, 1:14:33 AM (19 years ago)
Author:
bensch
Message:

orxonox/trunk: merged branches/parenting back to the.
merged with command:
svn merge branches/parenting trunk -r 3247:HEAD
resolved all conflicts in favor of parenting.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • orxonox/trunk/src/curve.cc

    r3217 r3365  
    1111   ### File Specific:
    1212   main-programmer: Benjamin Grauer
    13    co-programmer: ...
     13   co-programmer: Patrick Boenzli
     14
     15   ADD: Patrick Boenzli           B-Spline
     16
    1417
    1518   TODO:
    1619     local-Time implementation
    17      closed Bezier Curve
    1820     NURBS
    1921     
     
    2123
    2224#include "curve.h"
    23 
    24 
     25#include "matrix.h"
     26#include "debug.h"
     27
     28#include <math.h>
     29#include <stdio.h>
    2530
    2631/**
     
    3742  currentNode->next = 0; // not sure if this really points to NULL!!
    3843  currentNode->number = (++nodeCount);
     44  this->rebuild();
    3945  return;
    4046}
    4147
     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*/
     53Vector 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///////////////////////////////////
    4266
    4367/**
     
    4569*/
    4670BezierCurve::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*/
     80BezierCurve::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*/
     92BezierCurve::~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*/
     109void BezierCurve::init(void)
    47110{
    48111  nodeCount = 0;
     
    58121
    59122/**
    60    \brief Deletes a BezierCurve.
     123   \brief Rebuilds a Curve
     124*/
     125void 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*/
     167Vector 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*/
     199Vector 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*/
     209Quaternion 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*/
     219Vector 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*/
     232UPointCurve::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*/
     241UPointCurve::UPointCurve (int derivation)
     242{
     243  this->derivation = derivation;
     244  dirCurve=NULL;
     245  this->init();
     246}
     247
     248/**
     249   \brief Deletes a UPointCurve.
    61250
    62251   It does this by freeing all the space taken over from the nodes
    63252*/
    64 BezierCurve::~BezierCurve (void)
     253UPointCurve::~UPointCurve(void)
    65254{
    66255  PathNode* tmpNode;
     
    72261      delete tmpNode;
    73262    }
     263  if (dirCurve)
     264    delete dirCurve;
     265}
     266
     267/**
     268   \brief Initializes a UPointCurve
     269*/
     270void 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*/
     288void 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    }
    74328}
    75329
     
    79333   \return the Position on the Path
    80334*/
    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     }
     335Vector UPointCurve::calcPos(float t)
     336{
    89337  PathNode* tmpNode = firstNode;
    90    
    91338  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
    107347      tmpNode = tmpNode->next;
    108 
    109348    }
    110349  return ret;
     
    116355   \returns The vvaluated Vector.
    117356*/
    118 Vector BezierCurve::calcDir (float t)
     357Vector UPointCurve::calcDir (float t)
    119358{
    120359  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++;
    133370      tmpNode = tmpNode->next;
    134371    }
    135   ret = tmpCurve->calcPos(t);
    136372  ret.normalize();
    137 
    138373  return ret;
    139374}
     
    144379   \returns The evaluated Quaternion.
    145380*/
    146 Quaternion BezierCurve::calcQuat (float t)
     381Quaternion UPointCurve::calcQuat (float t)
    147382{
    148383  return Quaternion (calcDir(t), Vector(0,0,1));
     
    154389  \return a Vector to the calculated position
    155390*/
    156 Vector BezierCurve::getPos() const
     391Vector UPointCurve::getPos(void) const
    157392{
    158393  return curvePoint;
    159394}
    160 
    161 /**
    162    \brief ncr-calculator, did not find an other method
    163    \todo a c++ variante to do this
    164 */
    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.