00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00019
00026
00027
00028
00029 #ifndef VECTOR3D_H
00030 #define VECTOR3D_H
00031
00033
00034
00035 #include <cmath>
00036 #include <iostream>
00037
00038
00039 #include <point3d.h>
00040 #include <quaternion.h>
00041
00043 template<class T> class Vector3D
00044 {
00045 public:
00046 Vector3D();
00047 Vector3D(const T x, const T y, const T z);
00048 Vector3D(const T x1, const T y1, const T z1, const T x2, const T y2, const T z2);
00049 Vector3D(const Point3D<T> point1, const Point3D<T> point2);
00050 Vector3D(const Vector3D& v);
00051 ~Vector3D();
00052
00053
00054 bool isUnit() const;
00055 bool isZero() const;
00056 T x() const;
00057 T y() const;
00058 T z() const;
00059 T length() const;
00060
00061
00062 void setValues(const T x, const T y, const T z);
00063 void normalize();
00064 void setLength(const T newLength);
00065 void changeLength(const T amount);
00066 void invert();
00067 void add(const Vector3D v);
00068 void rotate(const Vector3D axis, const T angle);
00069 void setTorsion(const T angle, const Vector3D refBond, const Vector3D centralBond);
00070
00071
00072 Vector3D cross(const Vector3D v) const;
00073 T dot(const Vector3D v) const;
00074 T angle(const Vector3D v) const;
00075 T torsion(const Vector3D v1, const Vector3D v2) const;
00076
00077 private:
00078
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
00213 T scalingFactor = newLength/length();
00214
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
00226 T oldLength = length();
00227 if(oldLength < Point3D<T>::TOLERANCE)
00228 return;
00229 T scalingFactor = (oldLength + amount)/oldLength;
00230
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;
00308 Vector3D<T> vb = v2;
00309 Vector3D<T> vc = v1;
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
00323
00324
00325 T asinAngle = asin(argy/sqrt(argx*argx + argy*argy))*Point3D<T>::RADTODEG;
00326
00327
00329 #ifdef Q_OS_WIN32
00330 if(acosAngle == 90.0)
00331 return 90.0;
00332 else if(acosAngle > 90.0)
00333 #else
00334 if(acosAngle >= 90.0)
00335 #endif
00336 return -asinAngle;
00337 else if(asinAngle < 0.0)
00338 return asinAngle + 180.0;
00339 else
00340 return asinAngle - 180.0;
00341
00342 return 0.0;
00343 }
00344
00346 template <class T> void Vector3D<T>::setTorsion(const T angle, const Vector3D refBond, const Vector3D centralBond)
00350 {
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 std::cerr << "Vector3D::setTorsion not implemented yet. DO NOT USE" << std::endl;
00384 exit(1);
00385 }
00386
00387 #endif
00388