[Teleus-cvs] teleus/src/math vector.cpp,1.16,1.17 vector.hpp,1.13,1.14
Status: Inactive
Brought to you by:
spiffgq
|
From: Daniel R. <sp...@us...> - 2004-05-25 23:06:35
|
Update of /cvsroot/teleus/teleus/src/math In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16628/src/math Modified Files: vector.cpp vector.hpp Log Message: A lot of internal changes, bug fixes, comment updates, etc. Index: vector.hpp =================================================================== RCS file: /cvsroot/teleus/teleus/src/math/vector.hpp,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** vector.hpp 11 Mar 2004 03:14:44 -0000 1.13 --- vector.hpp 25 May 2004 23:06:24 -0000 1.14 *************** *** 37,42 **** struct Vector4d; typedef Vector4d Quaternion; ! struct Matrix_4X4; ! typedef Matrix_4X4 Matrix; struct Vector2d { --- 37,42 ---- struct Vector4d; typedef Vector4d Quaternion; ! struct Matrix3d; ! struct Matrix4d; struct Vector2d { *************** *** 76,79 **** --- 76,80 ---- const Vector3d normalized () const; bool isNormalized() const; + void verifyNormalized(); void zero (); void copy (const Vector3d &temp); *************** *** 146,152 **** inline Vector4d (double, double, double, double); inline Vector4d (const Vector4d&); ! void copy (const Vector4d& temp); ! void copy (const Matrix& temp); void normalize (); --- 147,156 ---- inline Vector4d (double, double, double, double); inline Vector4d (const Vector4d&); + /*inline Vector4d (const Matrix3d&); + inline Vector4d (const Matrix4d&);*/ ! void copy (const Vector4d&); ! /*void copy (const Matrix3d&); ! void copy (const Matrix4d&);*/ void normalize (); *************** *** 182,186 **** void setAngle (double angle, double x, double y, double z); void setValues (double x, double y, double z); ! void setEulerAngles (double r, double p, double y); const Vector3d directionVector () const; --- 186,190 ---- void setAngle (double angle, double x, double y, double z); void setValues (double x, double y, double z); ! void setEulerAngles (double, double, double); const Vector3d directionVector () const; *************** *** 194,198 **** const Vector4d& operator=(const Vector3d&); const Vector4d& operator=(const Vector4d&); ! const Vector4d& operator=(const Matrix&); const Vector4d operator-() const; --- 198,202 ---- const Vector4d& operator=(const Vector3d&); const Vector4d& operator=(const Vector4d&); ! //const Vector4d& operator=(const Matrix&); const Vector4d operator-() const; *************** *** 206,209 **** --- 210,215 ---- const Vector4d operator*(const Vector4d& v, const double d); const Vector4d operator*(const double d, const Vector4d& v); + const Vector4d operator*(const Vector4d&, const Vector3d&); + const Vector4d operator*(const Vector3d&, const Vector4d&); const Vector4d& operator*=(Vector4d& v, const double d); Index: vector.cpp =================================================================== RCS file: /cvsroot/teleus/teleus/src/math/vector.cpp,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** vector.cpp 11 Mar 2004 03:14:43 -0000 1.16 --- vector.cpp 25 May 2004 23:06:24 -0000 1.17 *************** *** 25,31 **** --- 25,33 ---- */ + #include <cstdio> #include <cmath> #include "physics.hpp" #include "vector.hpp" + #include "matrix.hpp" #include "debug.hpp" *************** *** 105,112 **** void Vector3d::normalize (){ ! double l = this->length(); ! this->x = this->x / l; ! this->y = this->y / l; ! this->z = this->z / l; } --- 107,118 ---- void Vector3d::normalize (){ ! double l = lengthSquared(); ! ! if (l == 0.0) { return; } ! l = sqrt(l); ! ! x /= l; ! y /= l; ! z /= l; } *************** *** 136,139 **** --- 142,164 ---- /** + * \brief Normalizes this vector if it is not already + * + * This method checks to see if this vector is already normalized. + * If not, it normalizes it. + * + * \author Daniel Royer + */ + void Vector3d::verifyNormalized() { + + double l = lengthSquared(); + if (l != 1.0 && l != 0.0){ + l = sqrt(l); + x /= l; + y /= l; + z /= l; + } + } + + /** * \brief Sets all components to zero * *************** *** 254,258 **** * \todo write this function */ ! void Vector3d::rotate (const Vector3d& /*axis*/, const double /*angle*/){ #if 0 --- 279,283 ---- * \todo write this function */ ! void Vector3d::rotate (const Vector3d& axis, const double angle){ #if 0 *************** *** 264,276 **** *this = result; #else ! assertNotReached(); #endif } ! void Vector3d::rotate (const Quaternion& /*q*/){ ! assertNotReached(); } /** * \brief Toggles between coordinate systems. --- 289,313 ---- *this = result; #else ! Quaternion temp; ! temp.setAxisAngle(axis, angle); ! rotate(temp); #endif } ! void Vector3d::rotate (const Quaternion& q){ ! Quaternion temp = q * (*this) * q.conjugated(); ! /* ! Quaternion temp = q; ! temp = temp * (*this); ! temp = temp * q.conjugated(); ! */ ! ! x = temp.x; ! y = temp.y; ! z = temp.z; } + /** * \brief Toggles between coordinate systems. *************** *** 743,749 **** * * \f[ ! * \vec{A} \cdot \vec{b} = AB \cos \theta ! * \cos \theta = \frac{\vec{A} \cdot \vec{B}}{AB} ! * \theta = \arccos(\frac{\vec{A} \cdot \vec{B}}{AB}) * \f] * --- 780,788 ---- * * \f[ ! * \begin{array}{rcl} ! * \vec{A} \cdot \vec{b} &=& AB \cos \theta \\ ! * \cos \theta &=& \frac{\vec{A} \cdot \vec{B}}{AB} \\ ! * \theta &=& \arccos(\frac{\vec{A} \cdot \vec{B}}{AB}) ! * \end{array} * \f] * *************** *** 772,775 **** --- 811,836 ---- * functionality. * + * The triple scalar product of the three vectors, + * \f$\vec{A}\f$, \f$\vec{B}\f$, \f$\vec{C}\f$, + * denoted as \f$ \left[\vec{A},\vec{B},\vec{C}\right] \f$ + * is defined by: + * + * \f[ + * \begin{array}{lcr} + * + * \left[\vec{A},\vec{B},\vec{C}\right] &=& \vec{A} \cdot \left( \vec{B} \times \vec{C} \right) \\ + * &=& \vec{B} \cdot \left( \vec{C} \times \vec{A} \right) \\ + * &=& \vec{C} \cdot \left( \vec{A} \times \vec{B} \right) + * \end{array} + * \f] + * + * where: + * \li \f$ \cdot \f$ is the vector dot product + * \li \f$ \times \f$ is the vector cross product + * + * The volume of a parallelepiped whose sides are given by the vectors + * A, B, and C is given by the absolute value of + * \f$ \left[\vec{A},\vec{B},\vec{C}\right] \f$. + * * \param a the first operand * \param b the second operand *************** *** 778,782 **** * * \author Daniel Royer - * \todo beef up this comment block */ const double tripleScalar (const Vector3d& a, const Vector3d& b, --- 839,842 ---- *************** *** 941,945 **** void Vector4d::normalize (){ ! double l = length(); w /= l; x /= l; --- 1001,1008 ---- void Vector4d::normalize (){ ! double l = lengthSquared(); ! if (l == 0.0) { return; } ! l = sqrt(l); ! w /= l; x /= l; *************** *** 948,951 **** --- 1011,1024 ---- } + /** + * \brief Returns a normalized version of this vector. + * + * This method returns a unit vector that points in the same + * direction as this vector. If this vector is already + * normalized, then these two vectors should be equal. + * + * \returns a normalized version of this vector + * \author Daniel Royer + */ const Vector4d Vector4d::normalized () const { *************** *** 973,982 **** } ! void Vector4d::copy (const Matrix& /*temp*/){ ! #warning Vector4d::copy() not written assertNotReached(); } /** * \brief Returns the length of this vector --- 1046,1063 ---- } ! #if 0 ! void Vector4d::copy (const Matrix3d& temp) { ! #warning Vector4d::setMatrix() not written assertNotReached(); } + void Vector4d::copy (const Matrix4d& temp) { + + #warning Vector4d::setMatrix() not written + assertNotReached(); + } + #endif + /** * \brief Returns the length of this vector *************** *** 993,996 **** --- 1074,1116 ---- } + /** + * \brief Returns the square of the length of this vector + * + * This method returns the length of this vector, squared. This + * is useful for times when you don't need to know the actual + * length of the vector, but you can infer all you need to know + * from the square of the lenght. This saves the square root + * call. + * + * For example, if you want to check to see if the vector is a + * unit vector, you don't need to know the actual length of this + * vector, you only need to know if the length is not 1. + * + * \code + * double lenSqrd = vec.lengthSquared(); + * if (lenSqrd != 1.0){ + * vec.normalize(); + * } + * \endcode + * + * Or we can generalize the above. For example, if we want to + * know if the length is 10.0, then we can check to see if the + * length squared is 100.0: + * + * \code + * double lenSqrd = vec.lengthSquared(); + * // Check to see if length of vector is 10.0 + * if (lenSqrd != 100.0){ + * // Do something + * } + * \endcode + * + * However, the above uses are micro-optimizations and probably + * won't be useful except in frequently used areas, like maybe + * collision detection. + * + * \returns the square of the length of this vector + * \author Daniel Royer + */ double Vector4d::lengthSquared() const { *************** *** 998,1002 **** } - void Vector4d::setAxisAngle (double /*ax*/, double /*ay*/, double /*az*/, double /*angle*/) --- 1118,1121 ---- *************** *** 1036,1095 **** } void Vector4d::postMultiply (const Vector4d &vtx){ - /*Vector4d temp(*this);*/ - /*temp.w = w; - temp.x = x; - temp.y = y; - temp.z = z;*/ multiplyAndSet (*this, vtx); - } - void Vector4d::multiplyAndSet (const Vector4d &v1, - const Vector4d &v2) - { ! w = v2.w * v1.w - ! v2.x * v1.x - ! v2.y * v1.y - ! v2.z * v1.z; ! ! x = v2.w * v1.x + ! v2.x * v1.w + ! v2.y * v1.z - ! v2.z * v1.y; ! ! y = v2.w * v1.y - ! v2.x * v1.z + ! v2.y * v1.w + ! v2.z * v1.x; ! ! z = v2.w * v1.z + ! v2.x * v1.y - ! v2.y * v1.x + ! v2.z * v1.w; ! ! #if 0 ! w = v2.v[0] * v1.v[0] - ! v2.v[1] * v1.v[1] - ! v2.v[2] * v1.v[2] - ! v2.v[3] * v1.v[3]; ! ! x = v2.v[0] * v1.v[1] + ! v2.v[1] * v1.v[0] + ! v2.v[2] * v1.v[3] - ! v2.v[3] * v1.v[2]; ! ! y = v2.v[0] * v1.v[2] - ! v2.v[1] * v1.v[3] + ! v2.v[2] * v1.v[0] + ! v2.v[3] * v1.v[1]; ! ! z = v2.v[0] * v1.v[3] + ! v2.v[1] * v1.v[2] - ! v2.v[2] * v1.v[1] + ! v2.v[3] * v1.v[0]; ! #endif } --- 1155,1199 ---- } + /** + * \brief Multiplies the vector to this vector + * + * This method multiplies the vector \a vtx to \c this vector + * and stores the result in \c this vector. + * + * \f[ + * \vec{V_{this}} = \vec{V_{this}} \times \vec{V_tx} + * \f] + * + * \param vtx the vector to multiply + * \author Daniel Royer + */ void Vector4d::postMultiply (const Vector4d &vtx){ multiplyAndSet (*this, vtx); } ! /** ! * \brief Multiplies two vectors and stores the result in this ! * vector. ! * ! * This method multiplies two vectors, \a v1, and \a v2, and ! * stores the product in \c this vector. ! * ! * \f[ ! * \vec{V_{this}} = \vec{V_1} \times \vec{V_2} ! * \f] ! * ! * \param a the first operand ! * \param b the second operand ! * \author Daniel Royer ! */ ! void Vector4d::multiplyAndSet (const Vector4d &a, ! const Vector4d &b) ! { ! w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z; ! x = a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y; ! y = a.w * b.y + a.y * b.w + a.z * b.x - a.x * b.z; ! z = a.w * b.z + a.z * b.w + a.x * b.y - a.y * b.x; } *************** *** 1114,1117 **** --- 1218,1234 ---- } + /** + * + * + * \f[ + * \vec{Q_x} = \langle x, 1.0, 0.0, 0.0 \rangle + * \vec{Q_y} = \langle y, 0.0, 1.0, 0.0 \rangle + * \vec{Q_z} = \langle z, 0.0, 0.0, 1.0 \rangle + * \vec{Q_x} = (\vec{Q_x} \times \vec{Q_y}) \times \vec{Q_z} + * \f] + * + * \todo Finish writing this comment block + * + */ void Vector4d::setValues (double x, double y, double z) { *************** *** 1159,1177 **** * \f] * ! * \param r the roll angle (x) ! * \param p the pitch angle (y) ! * \param y the yaw angle (z) ! * ! * \todo Turns out, this method is crap. Reimplement completely. ! * \warning do not use this method, yet. * ! * \author Daniel Royer, adapted from Bourg's ! * MakeQFromEulerAngles() function. */ ! void Vector4d::setEulerAngles (double r, double p, double y) { ! double roll = degreesToRadians(r); ! double pitch = degreesToRadians(p); ! double yaw = degreesToRadians(y); double cosYaw = cos(0.5 * yaw); --- 1276,1316 ---- * \f] * ! * \param rollDeg the roll angle (x) in degrees ! * \param pitchDeg the pitch angle (y) in degrees ! * \param yawDeg the yaw angle (z) in degrees * ! * \author Daniel Royer */ ! void Vector4d::setEulerAngles (double rollDeg, double pitchDeg, double yawDeg) { ! ! // ! // Implementation note: I tested both implementations, and ! // they both return identical answers to within ! // double-precision tolerance. So I also tested them for ! // speed. The results of the speed test are ambiguous. They ! // both perform very similarly. Oddly, the second version is ! // faster for fewer iterations (less than 1e6), which implies ! // that it has less overhead even though there are several ! // hidden method calls. The first one executes faster for a ! // very large number of iterations (>=1e6), but not by much. ! // ! // Conclusion: it's a toss up. They both work and they both ! // are sufficiently fast. ! // ! // -- ! // Daniel Royer ! // sp...@us... ! // 4 May 2004 ! // ! ! double roll = degreesToRadians(rollDeg); ! double pitch = degreesToRadians(pitchDeg); ! double yaw = degreesToRadians(yawDeg); ! ! #if 1 ! ! // First version, adapted from David M. Bourge's "Physics ! // for Game Developers". double cosYaw = cos(0.5 * yaw); *************** *** 1192,1210 **** y = (cosYawSinPitch * cosRoll) + (sinYawCosPitch * sinRoll); z = (sinYawCosPitch * cosRoll) - (cosYawSinPitch * sinRoll); - } ! const Vector3d Vector4d::directionVector () const { ! Vector4d temp = this->normalized(); ! Vector3d dir; ! dir.x = 2.0f * (temp.x * temp.z - temp.w * temp.y); ! dir.y = 2.0f * (temp.y * temp.z + temp.w * temp.x); ! dir.z = 1.0f - 2.0f * (temp.x * temp.x + ! temp.y * temp.y); ! return dir; } Vector4d Vector4d::getVector4d (double angle, double x, double y, double z) --- 1331,1358 ---- y = (cosYawSinPitch * cosRoll) + (sinYawCosPitch * sinRoll); z = (sinYawCosPitch * cosRoll) - (cosYawSinPitch * sinRoll); ! #else ! // Second version, adapted from mathematical description of ! // quaternions and rotation matrices from mathworld.com. ! // Quaternion format: <w, x, y, z> ! Vector4d rollQ (cos(0.5 * roll), sin(0.5 * roll), 0.0, 0.0); ! Vector4d pitchQ (cos(0.5 * pitch), 0.0, sin(0.5 * pitch), 0.0); ! Vector4d yawQ (cos(0.5 * yaw), 0.0, 0.0, sin(0.5 * yaw)); ! *this = rollQ * pitchQ * yawQ; ! ! #endif } + + + /** + * \brief Constructs and returns a vector + * + * \deprecated Use a constructor instead + * \author Daniel Royer + */ Vector4d Vector4d::getVector4d (double angle, double x, double y, double z) *************** *** 1217,1220 **** --- 1365,1374 ---- } + /** + * \brief Constructs and returns a vector + * + * \deprecated Use a constructor instead + * \author Daniel Royer + */ Vector4d Vector4d::getVector4d (double x, double y, double z) *************** *** 1229,1233 **** * * Sets the elements of this vector to ! * \f$ \langle 0, 0, 0, 1 \rangle \f$. * * \author Daniel Royer --- 1383,1387 ---- * * Sets the elements of this vector to ! * \f$ \langle 1, 0, 0, 0 \rangle \f$. * * \author Daniel Royer *************** *** 1265,1271 **** const Quaternion Vector4d::conjugated () const { ! Quaternion result = *this; result.conjugate(); ! return result; } --- 1419,1426 ---- const Quaternion Vector4d::conjugated () const { ! /*Quaternion result = *this; result.conjugate(); ! return result;*/ ! return Quaternion (w, -x, -y, -z); } *************** *** 1422,1425 **** --- 1577,1596 ---- } + const Vector3d Vector4d::directionVector () const { + + #warning Vector4d::directionVector() is not ready for use + assertNotReached(); + + Vector4d temp = this->normalized(); + Vector3d dir; + + dir.x = 2.0f * (temp.x * temp.z - temp.w * temp.y); + dir.y = 2.0f * (temp.y * temp.z + temp.w * temp.x); + dir.z = 1.0f - 2.0f * (temp.x * temp.x + + temp.y * temp.y); + + return dir; + } + /** * \todo Figure out what the hell this method does. Is it similar *************** *** 1430,1433 **** --- 1601,1607 ---- const Vector3d Vector4d::viewAxis () const { + #warning Vector4d::viewAxis() is not ready for use + assertNotReached(); + double x2, y2, z2, xx, xz, yy, yz, wx, wy; *************** *** 1456,1459 **** --- 1630,1636 ---- const Vector3d Vector4d::upAxis () const { + #warning Vector4d::upAxis() is not ready for use + assertNotReached(); + double x2, y2, z2, xx, xy, yz, zz, wx, wz; *************** *** 1482,1485 **** --- 1659,1665 ---- const Vector3d Vector4d::rightAxis () const { + #warning Vector4d::rightAxis() is not ready for use + assertNotReached(); + double x2, y2, z2, xy, xz, yy, zz, wy, wz; *************** *** 1540,1543 **** --- 1720,1724 ---- } + #if 0 /** * \brief Matrix to Quaternion assignment operator *************** *** 1556,1560 **** --- 1737,1746 ---- return *this; } + #endif + /** + * \brief Negation operator + * \author Daniel Royer + */ const Vector4d Vector4d::operator-() const { *************** *** 1584,1588 **** const bool operator== (const Vector4d & a, const Vector4d & b){ ! return (a.x == b.x) && (a.y == b.y) && (a.z == b.z) && (a.w == b.w); } --- 1770,1775 ---- const bool operator== (const Vector4d & a, const Vector4d & b){ ! return (a.x == b.x) && (a.y == b.y) && ! (a.z == b.z) && (a.w == b.w); } *************** *** 1602,1605 **** --- 1789,1795 ---- } + /** + * \relates Vector4d + */ const Vector4d operator/(const Vector4d& v, const double d) { *************** *** 1612,1615 **** --- 1802,1808 ---- } + /** + * \relates Vector4d + */ const Vector4d operator*(const Vector4d& v, const double d) { *************** *** 1622,1625 **** --- 1815,1821 ---- } + /** + * \relates Vector4d + */ const Vector4d operator*(const double d, const Vector4d& v) { *************** *** 1632,1635 **** --- 1828,1859 ---- } + /** + * \relates Vector4d + * \relates Vector3d + */ + const Vector4d operator*(const Vector4d& v4, const Vector3d& v3) { + + return Vector4d (-(v4.x*v3.x + v4.y*v3.y + v4.z*v3.z), + v4.w*v3.x + v4.y*v3.z - v4.z*v3.y, + v4.w*v3.y + v4.z*v3.x - v4.x*v3.z, + v4.w*v3.z + v4.x*v3.y - v4.y*v3.x); + } + + + /** + * \relates Vector4d + * \relates Vector3d + */ + const Vector4d operator*(const Vector3d& v3, const Vector4d& v4) { + + return Vector4d (-(v4.x*v3.x + v4.y*v3.y + v4.z*v3.z), + v4.w*v3.x + v4.z*v3.y - v4.y*v3.z, + v4.w*v3.y + v4.x*v3.z - v4.z*v3.x, + v4.w*v3.z + v4.y*v3.x - v4.x*v3.y); + } + + /** + * \relates Vector4d + */ const Vector4d& operator*=(Vector4d& v, const double d) { *************** *** 1641,1644 **** --- 1865,1871 ---- } + /** + * \relates Vector4d + */ const Vector4d& operator/=(Vector4d& v, const double d) { *************** *** 1650,1653 **** --- 1877,1883 ---- } + /** + * \relates Vector4d + */ const Vector4d operator+(const Vector4d& a, const Vector4d& b) { *************** *** 1660,1663 **** --- 1890,1896 ---- } + /** + * \relates Vector4d + */ const Vector4d operator-(const Vector4d& a, const Vector4d& b) { *************** *** 1670,1673 **** --- 1903,1909 ---- } + /** + * \relates Vector4d + */ const Vector4d& operator+=(Vector4d& a, const Vector4d& b) { *************** *** 1679,1682 **** --- 1915,1921 ---- } + /** + * \relates Vector4d + */ const Vector4d& operator-=(Vector4d& a, const Vector4d& b) { *************** *** 1688,1691 **** --- 1927,1933 ---- } + /** + * \relates Vector4d + */ const Quaternion operator* (const Quaternion & a, const Quaternion & b){ *************** *** 1695,1698 **** --- 1937,1943 ---- } + /** + * \relates Vector4d + */ const Quaternion& operator*=(Quaternion & a, const Quaternion & b){ *************** *** 1701,1704 **** --- 1946,1952 ---- } + /** + * \relates Vector4d + */ const Quaternion slerp (const Quaternion& a, const Quaternion& b, float t){ |