/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Benjamin Grauer co-programmer: ... TODO: local-Time implementation closed Bezier Curve NURBS */ #include "curve.h" /** \brief adds a new Node to the bezier Curve \param newNode a Vector to the position of the new node */ void Curve::addNode(const Vector& newNode) { if (nodeCount != 0 ) { currentNode = currentNode->next = new PathNode; } currentNode->position = newNode; currentNode->next = 0; // not sure if this really points to NULL!! currentNode->number = (++nodeCount); return; } /** \brief Creates a new BezierCurve */ BezierCurve::BezierCurve (void) { nodeCount = 0; firstNode = new PathNode; currentNode = firstNode; firstNode->position = Vector (.0, .0, .0); firstNode->number = 0; firstNode->next = 0; // not sure if this really points to NULL!! return; } /** \brief Deletes a BezierCurve. It does this by freeing all the space taken over from the nodes */ BezierCurve::~BezierCurve (void) { PathNode* tmpNode; currentNode = firstNode; while (tmpNode != 0) { tmpNode = currentNode; currentNode = currentNode->next; delete tmpNode; } } /** \brief calculates the Position on the curve \param t The position on the Curve (0<=t<=1) \return the Position on the Path */ Vector BezierCurve::calcPos(float t) { if (nodeCount <=4) { // if (verbose >= 1) // printf ("Please define at least 4 nodes, until now you have only defined %i.\n", nodeCount); return Vector(0,0,0); } PathNode* tmpNode = firstNode; Vector ret = Vector(0.0,0.0,0.0); double factor; int k=0; while(tmpNode!=0) { k++; factor = ncr (nodeCount, k); for (int j=0; jposition.x; ret.y += factor * tmpNode->position.y; ret.z += factor * tmpNode->position.z; tmpNode = tmpNode->next; } return ret; } /** \brief Calulates the direction of the Curve at time t. \param The time at which to evaluate the curve. \returns The vvaluated Vector. */ Vector BezierCurve::calcDir (float t) { PathNode* tmpNode = firstNode; BezierCurve* tmpCurve = new BezierCurve(); Vector ret; Vector tmpVector; while (tmpNode->next != 0) { tmpVector = (tmpNode->next->position)- (tmpNode->position); tmpVector.x*=(float)nodeCount; tmpVector.y*=(float)nodeCount; tmpVector.z*=(float)nodeCount; tmpCurve->addNode(tmpVector); tmpNode = tmpNode->next; } ret = tmpCurve->calcPos(t); ret.normalize(); return ret; } /** \brief Calculates the Quaternion needed for our rotations \param t The time at which to evaluate the cuve. \returns The evaluated Quaternion. */ Quaternion BezierCurve::calcQuat (float t) { return Quaternion (calcDir(t), Vector(0,0,1)); } /** \brief returns the Position of the point calculated on the Curve \return a Vector to the calculated position */ Vector BezierCurve::getPos() const { return curvePoint; } /** \brief ncr-calculator, did not find an other method \todo a c++ variante to do this */ int ncr(int n, int i) { int ret = 1; for (int k=1; k<=n; k++) ret*=k; for (int k=1; k<=i; k++) ret/=k; for (int k=1; k<=n-i; k++) ret/=k; return ret; }