vector3d.h

Go to the documentation of this file.
00001 /***************************************************************************
00002                           vector3d.h  -  description
00003                              -------------------
00004     begin                : Mon Mar 3 2003
00005     copyright            : (C) 2003-2006 by Ben Swerts
00006     email                : bswerts@users.sourceforge.net
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00019 
00026 
00027 
00028 
00029 #ifndef VECTOR3D_H
00030 #define VECTOR3D_H
00031 
00033 
00034 // C++ header files
00035 #include <cmath>
00036 #include <iostream>
00037 
00038 // Xbrabo header files
00039 #include <point3d.h>
00040 #include <quaternion.h>
00041 
00043 template<class T> class Vector3D
00044 {
00045   public:
00046     Vector3D();                         // default constructor
00047     Vector3D(const T x, const T y, const T z);    // constructs a vector (xyz)
00048     Vector3D(const T x1, const T y1, const T z1, const T x2, const T y2, const T z2);     // constructs a vector from point1 to point2
00049     Vector3D(const Point3D<T> point1, const Point3D<T> point2);       // constructs a vector from point1 to point2
00050     Vector3D(const Vector3D& v);        // copy constructor
00051     ~Vector3D();                        // destructor
00052 
00053     // public member functions for retrieving data
00054     bool isUnit() const;                // returns true of it's a unit vector
00055     bool isZero() const;                // returns true if the vector is zero
00056     T x() const;                        // returns the x-value
00057     T y() const;                        // returns the y-value
00058     T z() const;                        // returns the z-value
00059     T length() const;                   // returns the length of the vector
00060 
00061     // public member functions for changing data
00062     void setValues(const T x, const T y, const T z);        // sets the vector
00063     void normalize();                   // normalizes the vector
00064     void setLength(const T newLength);  // sets a new length for the vector
00065     void changeLength(const T amount);  // changes the length of the vector by amount
00066     void invert();                      // inverts the direction of the vector
00067     void add(const Vector3D v);         // adds the vector v
00068     void rotate(const Vector3D axis, const T angle);        // rotate the vector around the axis by an angle
00069     void setTorsion(const T angle, const Vector3D refBond, const Vector3D centralBond);   // sets the torsion angle
00070 
00071     // public member functions for data generation
00072     Vector3D cross(const Vector3D v) const;       // calculates the cross product of 2 vectors
00073     T dot(const Vector3D v) const;      // calculates the dot product of 2 vectors
00074     T angle(const Vector3D v) const;    // calculates the angle between 2 vectors
00075     T torsion(const Vector3D v1, const Vector3D v2) const;  // calculates the torsion angle with another vector
00076 
00077   private:
00078     // private member variables
00079     T xVect, yVect, zVect;              
00080 };
00081 
00085 
00087 template <class T> Vector3D<T>::Vector3D()
00089 {
00090   setValues(0.0, 0.0, 0.0);
00091 }
00092 
00094 template <class T> Vector3D<T>::Vector3D(const T x, const T y, const T z)
00097 {
00098   setValues(x, y, z);
00099 }
00100 
00102 template <class T> Vector3D<T>::Vector3D(const T x1, const T y1, const T z1, const T x2, const T y2, const T z2)
00105 {
00106   setValues(x2 - x1, y2 - y1, z2 - z1);
00107 }
00108 
00110 template <class T> Vector3D<T>::Vector3D(const Point3D<T> point1, const Point3D<T> point2)
00113 {
00114   setValues(point2.x() - point1.x(), point2.y() - point1.y(), point2.z() - point1.z());
00115 }
00116 
00118 template <class T> Vector3D<T>::Vector3D(const Vector3D& v)
00120 {
00121   xVect = v.xVect;
00122   yVect = v.yVect;
00123   zVect = v.zVect;
00124 }
00125 
00127 template <class T> Vector3D<T>::~Vector3D()
00129 {
00130 
00131 }
00132 
00134 template <class T> bool Vector3D<T>::isUnit() const
00136 {
00137   if(fabs(length() - 1.0) < Point3D<T>::TOLERANCE)
00138     return true;
00139   else
00140     return false;
00141 }
00142 
00144 template <class T> bool Vector3D<T>::isZero() const
00146 {
00147   if(fabs(length()) < Point3D<T>::TOLERANCE)
00148     return true;
00149   else
00150     return false;
00151 }
00152 
00154 template <class T> T Vector3D<T>::x() const
00156 {
00157   return xVect;
00158 }
00159 
00161 template <class T> T Vector3D<T>::y() const
00163 {
00164   return yVect;
00165 }
00167 template <class T> T Vector3D<T>::z() const
00169 {
00170   return zVect;
00171 }
00172 
00174 template <class T> T Vector3D<T>::length() const
00176 {
00177   return sqrt(xVect*xVect + yVect*yVect + zVect*zVect);
00178 }
00179 
00181 template <class T> void Vector3D<T>::setValues(const T x, const T y, const T z)
00183 {
00184   xVect = x;
00185   yVect = y;
00186   zVect = z;
00187 }
00188 
00190 template <class T> void Vector3D<T>::normalize()
00192 {
00193   T len = length();
00194   if(len < Point3D<T>::TOLERANCE)
00195   {
00196     xVect = 0.0;
00197     yVect = 0.0;
00198     zVect = 0.0;
00199   }
00200   else
00201   {
00202     xVect = xVect/len;
00203     yVect = yVect/len;
00204     zVect = zVect/len;
00205   }
00206 }
00207 
00209 template <class T> void Vector3D<T>::setLength(const T newLength)
00211 {
00212   // determine the scaling factor
00213   T scalingFactor = newLength/length();
00214   // scale the values
00215   xVect *= scalingFactor;
00216   yVect *= scalingFactor;
00217   zVect *= scalingFactor;
00218 
00219 }
00220 
00222 template <class T> void Vector3D<T>::changeLength(const T amount)
00224 {
00225   // determine the scaling factor
00226   T oldLength = length();
00227   if(oldLength < Point3D<T>::TOLERANCE)
00228     return;
00229   T scalingFactor = (oldLength + amount)/oldLength;
00230   // scale the values
00231   xVect *= scalingFactor;
00232   yVect *= scalingFactor;
00233   zVect *= scalingFactor;
00234 
00235 }
00236 
00238 template <class T> void Vector3D<T>::invert()
00240 {
00241   xVect = -xVect;
00242   yVect = -yVect;
00243   zVect = -zVect;
00244 }
00245 
00247 template <class T> void Vector3D<T>::add(const Vector3D v)
00249 {
00250   xVect += v.xVect;
00251   yVect += v.yVect;
00252   zVect += v.zVect;
00253 }
00254 
00256 template <class T> void Vector3D<T>::rotate(const Vector3D axis, const T angle)
00258 {
00260   Quaternion<T> rotation(axis, angle);
00262   Quaternion<T> inverse = rotation;
00263   inverse.inverse();
00265   Quaternion<T> thisVector(0.0, xVect, yVect, zVect);
00267   Quaternion<T> result = rotation*thisVector*inverse;
00268   result.normalize();
00269   setValues(result.x(), result.y(), result.z());
00270 }
00271 
00273 template <class T> Vector3D<T> Vector3D<T>::cross(const Vector3D v) const
00275 {
00276   T resultX = yVect * v.zVect - v.yVect * zVect;
00277   T resultY = zVect * v.xVect - v.zVect * xVect;
00278   T resultZ = xVect * v.yVect - v.xVect * yVect;
00279 
00280   return Vector3D(resultX, resultY, resultZ);
00281 }
00282 
00284 template <class T> T Vector3D<T>::dot(const Vector3D v) const
00286 {
00287   return xVect*v.xVect + yVect * v.yVect + zVect * v.zVect;
00288 }
00289 
00291 template <class T> T Vector3D<T>::angle(const Vector3D v) const
00294 {
00295   Vector3D<T> v1 = v;
00296   Vector3D<T> v2 = *this;
00297   v1.normalize();
00298   v2.normalize();
00299   return acos(v1.dot(v2))*Point3D<T>::RADTODEG;
00300 }
00301 
00303 template <class T> T Vector3D<T>::torsion(const Vector3D v1, const Vector3D v2) const
00306 {
00307   Vector3D<T> va = *this; // the first vector
00308   Vector3D<T> vb = v2; // the central vector
00309   Vector3D<T> vc = v1; // the second vector
00310 
00311   va.normalize();
00312   vb.normalize();
00313   vc.normalize();
00314 
00316   T argx = - va.dot(vc) + va.dot(vb) * vb.dot(vc);
00317   T argy = va.dot(vb.cross(vc));
00318 
00320   T acosAngle = acos(argx/sqrt(argx*argx + argy*argy))*Point3D<T>::RADTODEG;
00322 //#ifdef Q_OS_WIN32
00323 //  T asinAngle = asin(argy/sqrt(hypot(argx, argy)))*RADTODEG; //=> doesn't work too well when using templates
00324 //#else
00325   T asinAngle = asin(argy/sqrt(argx*argx + argy*argy))*Point3D<T>::RADTODEG;
00326 //#endif
00327 
00329 #ifdef Q_OS_WIN32
00330   if(acosAngle == 90.0)
00331     return 90.0; // because the 'hypot' trick doesn't work when changing to template code
00332   else if(acosAngle > 90.0)
00333 #else      
00334   if(acosAngle >= 90.0) // 1st and 4th
00335 #endif
00336     return -asinAngle;
00337   else if(asinAngle < 0.0) // 3rd
00338     return asinAngle + 180.0;
00339   else
00340     return asinAngle - 180.0; // 2nd
00341 
00342   return 0.0; // omits warnings
00343 }
00344 
00346 template <class T> void Vector3D<T>::setTorsion(const T angle, const Vector3D refBond, const Vector3D centralBond)
00350 {
00351   // new implementation: - get the current torsion angle
00352   //                     - calculate the difference with the requested torsion angle
00353   //                     - call rotate() to do the rotation around the central bond
00354 
00355   /*
00356   T torsionAngle = angle * DEGTORAD;
00357   Vector3D va = *this;
00358   Vector3D vb = centralBond;
00359   Vector3D vc = centralBond;
00360   vc.invert();
00361   Vector3D vd = refBond;
00362 
00363   T orgLength = va.length();
00364   va.normalize();
00365   vb.normalize();
00366   vc.normalize();
00367   vd.normalize();
00368 
00369   Vector3D v1 = va.cross(vb);
00370   Vector3D v2 = vc.cross(vd);
00371 
00372   while(torsionAngle > 180.0f)
00373     torsionAngle -= 360.0f;
00374   while(torsionAngle < -180.0f)
00375     torsionAngle += 360.0f;
00376 
00377   if(torsionAngle <= 90.0f && torsionAngle >= -90.0f) // 1st or 4th quadrant
00378   {
00379     v1.rotate(vb, torsionAngle);
00380   }
00381   */
00382 
00383   std::cerr << "Vector3D::setTorsion not implemented yet. DO NOT USE" << std::endl;
00384   exit(1);
00385 }
00386 
00387 #endif
00388 

Generated on Fri May 19 14:31:56 2006 for Brabosphere by  doxygen 1.4.6-NO