Changeset 0d111b for molecuilder/src/vector.cpp
- Timestamp:
- Apr 29, 2010, 1:55:21 PM (16 years ago)
- Children:
- 070651, 5d1a94
- Parents:
- 90c4460 (diff), 32842d8 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - File:
-
- 1 edited
-
molecuilder/src/vector.cpp (modified) (43 diffs)
Legend:
- Unmodified
- Added
- Removed
-
molecuilder/src/vector.cpp
r90c4460 r0d111b 6 6 7 7 8 #include "defs.hpp"9 #include "helpers.hpp"10 #include "info.hpp"11 #include "gslmatrix.hpp"12 #include "leastsquaremin.hpp"13 #include "log.hpp"14 #include "memoryallocator.hpp"15 8 #include "vector.hpp" 16 9 #include "verbose.hpp" 17 10 #include "World.hpp" 18 19 #include <gsl/gsl_linalg.h> 20 #include <gsl/gsl_matrix.h> 21 #include <gsl/gsl_permutation.h> 22 #include <gsl/gsl_vector.h> 11 #include "Helpers/Assert.hpp" 12 #include "Helpers/fast_functions.hpp" 13 14 #include <iostream> 15 16 using namespace std; 17 23 18 24 19 /************************************ Functions for class vector ************************************/ … … 26 21 /** Constructor of class vector. 27 22 */ 28 Vector::Vector() { x[0] = x[1] = x[2] = 0.; }; 23 Vector::Vector() 24 { 25 x[0] = x[1] = x[2] = 0.; 26 }; 27 28 /** 29 * Copy constructor 30 */ 31 32 Vector::Vector(const Vector& src) 33 { 34 x[0] = src[0]; 35 x[1] = src[1]; 36 x[2] = src[2]; 37 } 29 38 30 39 /** Constructor of class vector. 31 40 */ 32 Vector::Vector(const Vector * const a)33 { 34 x[0] = a->x[0];35 x[1] = a->x[1];36 x[2] = a->x[2];37 }; 38 39 /** Constructor of class vector.40 * /41 Vector::Vector(const Vector &a) 42 {43 x[0] = a.x[0];44 x[1] = a.x[1];45 x[2] = a.x[2];46 };47 48 /** Constructor of class vector. 49 */50 Vector::Vector(const double x1, const double x2, const double x3) { x[0] = x1; x[1] = x2; x[2] = x3; }; 41 Vector::Vector(const double x1, const double x2, const double x3) 42 { 43 x[0] = x1; 44 x[1] = x2; 45 x[2] = x3; 46 }; 47 48 /** 49 * Assignment operator 50 */ 51 Vector& Vector::operator=(const Vector& src){ 52 // check for self assignment 53 if(&src!=this){ 54 x[0] = src[0]; 55 x[1] = src[1]; 56 x[2] = src[2]; 57 } 58 return *this; 59 } 51 60 52 61 /** Desctructor of class vector. … … 58 67 * \return \f$| x - y |^2\f$ 59 68 */ 60 double Vector::DistanceSquared(const Vector * consty) const69 double Vector::DistanceSquared(const Vector &y) const 61 70 { 62 71 double res = 0.; 63 72 for (int i=NDIM;i--;) 64 res += (x[i]-y ->x[i])*(x[i]-y->x[i]);73 res += (x[i]-y[i])*(x[i]-y[i]); 65 74 return (res); 66 75 }; … … 70 79 * \return \f$| x - y |\f$ 71 80 */ 72 double Vector::Distance(const Vector * const y) const 73 { 74 double res = 0.; 75 for (int i=NDIM;i--;) 76 res += (x[i]-y->x[i])*(x[i]-y->x[i]); 77 return (sqrt(res)); 81 double Vector::Distance(const Vector &y) const 82 { 83 return (sqrt(DistanceSquared(y))); 78 84 }; 79 85 … … 83 89 * \return \f$| x - y |\f$ 84 90 */ 85 double Vector::PeriodicDistance(const Vector * consty, const double * const cell_size) const91 double Vector::PeriodicDistance(const Vector &y, const double * const cell_size) const 86 92 { 87 93 double res = Distance(y), tmp, matrix[NDIM*NDIM]; 88 Vector Shiftedy, TranslationVector; 89 int N[NDIM]; 90 matrix[0] = cell_size[0]; 91 matrix[1] = cell_size[1]; 92 matrix[2] = cell_size[3]; 93 matrix[3] = cell_size[1]; 94 matrix[4] = cell_size[2]; 95 matrix[5] = cell_size[4]; 96 matrix[6] = cell_size[3]; 97 matrix[7] = cell_size[4]; 98 matrix[8] = cell_size[5]; 99 // in order to check the periodic distance, translate one of the vectors into each of the 27 neighbouring cells 100 for (N[0]=-1;N[0]<=1;N[0]++) 101 for (N[1]=-1;N[1]<=1;N[1]++) 102 for (N[2]=-1;N[2]<=1;N[2]++) { 103 // create the translation vector 104 TranslationVector.Zero(); 105 for (int i=NDIM;i--;) 106 TranslationVector.x[i] = (double)N[i]; 107 TranslationVector.MatrixMultiplication(matrix); 108 // add onto the original vector to compare with 109 Shiftedy.CopyVector(y); 110 Shiftedy.AddVector(&TranslationVector); 111 // get distance and compare with minimum so far 112 tmp = Distance(&Shiftedy); 113 if (tmp < res) res = tmp; 114 } 115 return (res); 94 Vector Shiftedy, TranslationVector; 95 int N[NDIM]; 96 matrix[0] = cell_size[0]; 97 matrix[1] = cell_size[1]; 98 matrix[2] = cell_size[3]; 99 matrix[3] = cell_size[1]; 100 matrix[4] = cell_size[2]; 101 matrix[5] = cell_size[4]; 102 matrix[6] = cell_size[3]; 103 matrix[7] = cell_size[4]; 104 matrix[8] = cell_size[5]; 105 // in order to check the periodic distance, translate one of the vectors into each of the 27 neighbouring cells 106 for (N[0]=-1;N[0]<=1;N[0]++) 107 for (N[1]=-1;N[1]<=1;N[1]++) 108 for (N[2]=-1;N[2]<=1;N[2]++) { 109 // create the translation vector 110 TranslationVector.Zero(); 111 for (int i=NDIM;i--;) 112 TranslationVector[i] = (double)N[i]; 113 TranslationVector.MatrixMultiplication(matrix); 114 // add onto the original vector to compare with 115 Shiftedy = y + TranslationVector; 116 // get distance and compare with minimum so far 117 tmp = Distance(Shiftedy); 118 if (tmp < res) res = tmp; 119 } 120 return (res); 116 121 }; 117 122 … … 121 126 * \return \f$| x - y |^2\f$ 122 127 */ 123 double Vector::PeriodicDistanceSquared(const Vector * consty, const double * const cell_size) const128 double Vector::PeriodicDistanceSquared(const Vector &y, const double * const cell_size) const 124 129 { 125 130 double res = DistanceSquared(y), tmp, matrix[NDIM*NDIM]; 126 Vector Shiftedy, TranslationVector; 127 int N[NDIM]; 128 matrix[0] = cell_size[0]; 129 matrix[1] = cell_size[1]; 130 matrix[2] = cell_size[3]; 131 matrix[3] = cell_size[1]; 132 matrix[4] = cell_size[2]; 133 matrix[5] = cell_size[4]; 134 matrix[6] = cell_size[3]; 135 matrix[7] = cell_size[4]; 136 matrix[8] = cell_size[5]; 137 // in order to check the periodic distance, translate one of the vectors into each of the 27 neighbouring cells 138 for (N[0]=-1;N[0]<=1;N[0]++) 139 for (N[1]=-1;N[1]<=1;N[1]++) 140 for (N[2]=-1;N[2]<=1;N[2]++) { 141 // create the translation vector 142 TranslationVector.Zero(); 143 for (int i=NDIM;i--;) 144 TranslationVector.x[i] = (double)N[i]; 145 TranslationVector.MatrixMultiplication(matrix); 146 // add onto the original vector to compare with 147 Shiftedy.CopyVector(y); 148 Shiftedy.AddVector(&TranslationVector); 149 // get distance and compare with minimum so far 150 tmp = DistanceSquared(&Shiftedy); 151 if (tmp < res) res = tmp; 152 } 153 return (res); 131 Vector Shiftedy, TranslationVector; 132 int N[NDIM]; 133 matrix[0] = cell_size[0]; 134 matrix[1] = cell_size[1]; 135 matrix[2] = cell_size[3]; 136 matrix[3] = cell_size[1]; 137 matrix[4] = cell_size[2]; 138 matrix[5] = cell_size[4]; 139 matrix[6] = cell_size[3]; 140 matrix[7] = cell_size[4]; 141 matrix[8] = cell_size[5]; 142 // in order to check the periodic distance, translate one of the vectors into each of the 27 neighbouring cells 143 for (N[0]=-1;N[0]<=1;N[0]++) 144 for (N[1]=-1;N[1]<=1;N[1]++) 145 for (N[2]=-1;N[2]<=1;N[2]++) { 146 // create the translation vector 147 TranslationVector.Zero(); 148 for (int i=NDIM;i--;) 149 TranslationVector[i] = (double)N[i]; 150 TranslationVector.MatrixMultiplication(matrix); 151 // add onto the original vector to compare with 152 Shiftedy = y + TranslationVector; 153 // get distance and compare with minimum so far 154 tmp = DistanceSquared(Shiftedy); 155 if (tmp < res) res = tmp; 156 } 157 return (res); 154 158 }; 155 159 … … 160 164 void Vector::KeepPeriodic(const double * const matrix) 161 165 { 162 // int N[NDIM]; 163 // bool flag = false; 164 //vector Shifted, TranslationVector; 165 Vector TestVector; 166 // Log() << Verbose(1) << "Begin of KeepPeriodic." << endl; 167 // Log() << Verbose(2) << "Vector is: "; 168 // Output(out); 169 // Log() << Verbose(0) << endl; 170 TestVector.CopyVector(this); 171 TestVector.InverseMatrixMultiplication(matrix); 172 for(int i=NDIM;i--;) { // correct periodically 173 if (TestVector.x[i] < 0) { // get every coefficient into the interval [0,1) 174 TestVector.x[i] += ceil(TestVector.x[i]); 175 } else { 176 TestVector.x[i] -= floor(TestVector.x[i]); 166 // int N[NDIM]; 167 // bool flag = false; 168 //vector Shifted, TranslationVector; 169 // Log() << Verbose(1) << "Begin of KeepPeriodic." << endl; 170 // Log() << Verbose(2) << "Vector is: "; 171 // Output(out); 172 // Log() << Verbose(0) << endl; 173 InverseMatrixMultiplication(matrix); 174 for(int i=NDIM;i--;) { // correct periodically 175 if (at(i) < 0) { // get every coefficient into the interval [0,1) 176 at(i) += ceil(at(i)); 177 } else { 178 at(i) -= floor(at(i)); 179 } 177 180 } 178 } 179 TestVector.MatrixMultiplication(matrix); 180 CopyVector(&TestVector); 181 // Log() << Verbose(2) << "New corrected vector is: "; 182 // Output(out); 183 // Log() << Verbose(0) << endl; 184 // Log() << Verbose(1) << "End of KeepPeriodic." << endl; 181 MatrixMultiplication(matrix); 182 // Log() << Verbose(2) << "New corrected vector is: "; 183 // Output(out); 184 // Log() << Verbose(0) << endl; 185 // Log() << Verbose(1) << "End of KeepPeriodic." << endl; 185 186 }; 186 187 … … 189 190 * \return \f$\langle x, y \rangle\f$ 190 191 */ 191 double Vector::ScalarProduct(const Vector * consty) const192 double Vector::ScalarProduct(const Vector &y) const 192 193 { 193 194 double res = 0.; 194 195 for (int i=NDIM;i--;) 195 res += x[i]*y ->x[i];196 res += x[i]*y[i]; 196 197 return (res); 197 198 }; … … 204 205 * \return \f$ x \times y \f& 205 206 */ 206 void Vector::VectorProduct(const Vector * consty)207 void Vector::VectorProduct(const Vector &y) 207 208 { 208 209 Vector tmp; 209 tmp .x[0] = x[1]* (y->x[2]) - x[2]* (y->x[1]);210 tmp .x[1] = x[2]* (y->x[0]) - x[0]* (y->x[2]);211 tmp .x[2] = x[0]* (y->x[1]) - x[1]* (y->x[0]);212 this->CopyVector(&tmp);210 tmp[0] = x[1]* (y[2]) - x[2]* (y[1]); 211 tmp[1] = x[2]* (y[0]) - x[0]* (y[2]); 212 tmp[2] = x[0]* (y[1]) - x[1]* (y[0]); 213 (*this) = tmp; 213 214 }; 214 215 … … 218 219 * \return \f$\langle x, y \rangle\f$ 219 220 */ 220 void Vector::ProjectOntoPlane(const Vector * consty)221 void Vector::ProjectOntoPlane(const Vector &y) 221 222 { 222 223 Vector tmp; 223 tmp .CopyVector(y);224 tmp = y; 224 225 tmp.Normalize(); 225 tmp.Scale(ScalarProduct(&tmp)); 226 this->SubtractVector(&tmp); 227 }; 228 229 /** Calculates the intersection point between a line defined by \a *LineVector and \a *LineVector2 and a plane defined by \a *Normal and \a *PlaneOffset. 230 * According to [Bronstein] the vectorial plane equation is: 231 * -# \f$\stackrel{r}{\rightarrow} \cdot \stackrel{N}{\rightarrow} + D = 0\f$, 232 * where \f$\stackrel{r}{\rightarrow}\f$ is the vector to be testet, \f$\stackrel{N}{\rightarrow}\f$ is the plane's normal vector and 233 * \f$D = - \stackrel{a}{\rightarrow} \stackrel{N}{\rightarrow}\f$, the offset with respect to origin, if \f$\stackrel{a}{\rightarrow}\f$, 234 * is an offset vector onto the plane. The line is parametrized by \f$\stackrel{x}{\rightarrow} + k \stackrel{t}{\rightarrow}\f$, where 235 * \f$\stackrel{x}{\rightarrow}\f$ is the offset and \f$\stackrel{t}{\rightarrow}\f$ the directional vector (NOTE: No need to normalize 236 * the latter). Inserting the parametrized form into the plane equation and solving for \f$k\f$, which we insert then into the parametrization 237 * of the line yields the intersection point on the plane. 238 * \param *out output stream for debugging 239 * \param *PlaneNormal Plane's normal vector 240 * \param *PlaneOffset Plane's offset vector 241 * \param *Origin first vector of line 242 * \param *LineVector second vector of line 243 * \return true - \a this contains intersection point on return, false - line is parallel to plane (even if in-plane) 244 */ 245 bool Vector::GetIntersectionWithPlane(const Vector * const PlaneNormal, const Vector * const PlaneOffset, const Vector * const Origin, const Vector * const LineVector) 246 { 247 Info FunctionInfo(__func__); 248 double factor; 249 Vector Direction, helper; 250 251 // find intersection of a line defined by Offset and Direction with a plane defined by triangle 252 Direction.CopyVector(LineVector); 253 Direction.SubtractVector(Origin); 254 Direction.Normalize(); 255 DoLog(1) && (Log() << Verbose(1) << "INFO: Direction is " << Direction << "." << endl); 256 //Log() << Verbose(1) << "INFO: PlaneNormal is " << *PlaneNormal << " and PlaneOffset is " << *PlaneOffset << "." << endl; 257 factor = Direction.ScalarProduct(PlaneNormal); 258 if (fabs(factor) < MYEPSILON) { // Uniqueness: line parallel to plane? 259 DoLog(1) && (Log() << Verbose(1) << "BAD: Line is parallel to plane, no intersection." << endl); 260 return false; 261 } 262 helper.CopyVector(PlaneOffset); 263 helper.SubtractVector(Origin); 264 factor = helper.ScalarProduct(PlaneNormal)/factor; 265 if (fabs(factor) < MYEPSILON) { // Origin is in-plane 266 DoLog(1) && (Log() << Verbose(1) << "GOOD: Origin of line is in-plane." << endl); 267 CopyVector(Origin); 268 return true; 269 } 270 //factor = Origin->ScalarProduct(PlaneNormal)*(-PlaneOffset->ScalarProduct(PlaneNormal))/(Direction.ScalarProduct(PlaneNormal)); 271 Direction.Scale(factor); 272 CopyVector(Origin); 273 DoLog(1) && (Log() << Verbose(1) << "INFO: Scaled direction is " << Direction << "." << endl); 274 AddVector(&Direction); 275 276 // test whether resulting vector really is on plane 277 helper.CopyVector(this); 278 helper.SubtractVector(PlaneOffset); 279 if (helper.ScalarProduct(PlaneNormal) < MYEPSILON) { 280 DoLog(1) && (Log() << Verbose(1) << "GOOD: Intersection is " << *this << "." << endl); 281 return true; 282 } else { 283 DoeLog(2) && (eLog()<< Verbose(2) << "Intersection point " << *this << " is not on plane." << endl); 284 return false; 285 } 226 tmp.Scale(ScalarProduct(tmp)); 227 *this -= tmp; 286 228 }; 287 229 … … 290 232 * \param *PlaneNormal normal of plane 291 233 * \param *PlaneOffset offset of plane 234 * \return distance to plane 292 235 * \return distance vector onto to plane 293 236 */ 294 Vector Vector::GetDistanceVectorToPlane(const Vector * const PlaneNormal, const Vector * const PlaneOffset) const 295 { 296 Vector temp; 297 298 // first create part that is orthonormal to PlaneNormal with withdraw 299 temp.CopyVector(this); 300 temp.SubtractVector(PlaneOffset); 301 temp.MakeNormalVector(PlaneNormal); 237 Vector Vector::GetDistanceVectorToPlane(const Vector &PlaneNormal, const Vector &PlaneOffset) const 238 { 239 Vector temp = (*this) - PlaneOffset; 240 temp.MakeNormalTo(PlaneNormal); 302 241 temp.Scale(-1.); 303 242 // then add connecting vector from plane to point 304 temp.AddVector(this); 305 temp.SubtractVector(PlaneOffset); 243 temp += (*this)-PlaneOffset; 306 244 double sign = temp.ScalarProduct(PlaneNormal); 307 245 if (fabs(sign) > MYEPSILON) … … 314 252 return temp; 315 253 }; 254 316 255 317 256 /** Calculates the minimum distance of this vector to the plane. … … 322 261 * \return distance to plane 323 262 */ 324 double Vector::DistanceToPlane(const Vector * const PlaneNormal, const Vector * constPlaneOffset) const263 double Vector::DistanceToPlane(const Vector &PlaneNormal, const Vector &PlaneOffset) const 325 264 { 326 265 return GetDistanceVectorToPlane(PlaneNormal,PlaneOffset).Norm(); 327 };328 329 /** Calculates the intersection of the two lines that are both on the same plane.330 * This is taken from Weisstein, Eric W. "Line-Line Intersection." From MathWorld--A Wolfram Web Resource. http://mathworld.wolfram.com/Line-LineIntersection.html331 * \param *out output stream for debugging332 * \param *Line1a first vector of first line333 * \param *Line1b second vector of first line334 * \param *Line2a first vector of second line335 * \param *Line2b second vector of second line336 * \param *PlaneNormal normal of plane, is supplemental/arbitrary337 * \return true - \a this will contain the intersection on return, false - lines are parallel338 */339 bool Vector::GetIntersectionOfTwoLinesOnPlane(const Vector * const Line1a, const Vector * const Line1b, const Vector * const Line2a, const Vector * const Line2b, const Vector *PlaneNormal)340 {341 Info FunctionInfo(__func__);342 343 GSLMatrix *M = new GSLMatrix(4,4);344 345 M->SetAll(1.);346 for (int i=0;i<3;i++) {347 M->Set(0, i, Line1a->x[i]);348 M->Set(1, i, Line1b->x[i]);349 M->Set(2, i, Line2a->x[i]);350 M->Set(3, i, Line2b->x[i]);351 }352 353 //Log() << Verbose(1) << "Coefficent matrix is:" << endl;354 //ostream &output = Log() << Verbose(1);355 //for (int i=0;i<4;i++) {356 // for (int j=0;j<4;j++)357 // output << "\t" << M->Get(i,j);358 // output << endl;359 //}360 if (fabs(M->Determinant()) > MYEPSILON) {361 DoLog(1) && (Log() << Verbose(1) << "Determinant of coefficient matrix is NOT zero." << endl);362 return false;363 }364 delete(M);365 DoLog(1) && (Log() << Verbose(1) << "INFO: Line1a = " << *Line1a << ", Line1b = " << *Line1b << ", Line2a = " << *Line2a << ", Line2b = " << *Line2b << "." << endl);366 367 368 // constuct a,b,c369 Vector a;370 Vector b;371 Vector c;372 Vector d;373 a.CopyVector(Line1b);374 a.SubtractVector(Line1a);375 b.CopyVector(Line2b);376 b.SubtractVector(Line2a);377 c.CopyVector(Line2a);378 c.SubtractVector(Line1a);379 d.CopyVector(Line2b);380 d.SubtractVector(Line1b);381 DoLog(1) && (Log() << Verbose(1) << "INFO: a = " << a << ", b = " << b << ", c = " << c << "." << endl);382 if ((a.NormSquared() < MYEPSILON) || (b.NormSquared() < MYEPSILON)) {383 Zero();384 DoLog(1) && (Log() << Verbose(1) << "At least one of the lines is ill-defined, i.e. offset equals second vector." << endl);385 return false;386 }387 388 // check for parallelity389 Vector parallel;390 double factor = 0.;391 if (fabs(a.ScalarProduct(&b)*a.ScalarProduct(&b)/a.NormSquared()/b.NormSquared() - 1.) < MYEPSILON) {392 parallel.CopyVector(Line1a);393 parallel.SubtractVector(Line2a);394 factor = parallel.ScalarProduct(&a)/a.Norm();395 if ((factor >= -MYEPSILON) && (factor - 1. < MYEPSILON)) {396 CopyVector(Line2a);397 DoLog(1) && (Log() << Verbose(1) << "Lines conincide." << endl);398 return true;399 } else {400 parallel.CopyVector(Line1a);401 parallel.SubtractVector(Line2b);402 factor = parallel.ScalarProduct(&a)/a.Norm();403 if ((factor >= -MYEPSILON) && (factor - 1. < MYEPSILON)) {404 CopyVector(Line2b);405 DoLog(1) && (Log() << Verbose(1) << "Lines conincide." << endl);406 return true;407 }408 }409 DoLog(1) && (Log() << Verbose(1) << "Lines are parallel." << endl);410 Zero();411 return false;412 }413 414 // obtain s415 double s;416 Vector temp1, temp2;417 temp1.CopyVector(&c);418 temp1.VectorProduct(&b);419 temp2.CopyVector(&a);420 temp2.VectorProduct(&b);421 DoLog(1) && (Log() << Verbose(1) << "INFO: temp1 = " << temp1 << ", temp2 = " << temp2 << "." << endl);422 if (fabs(temp2.NormSquared()) > MYEPSILON)423 s = temp1.ScalarProduct(&temp2)/temp2.NormSquared();424 else425 s = 0.;426 DoLog(1) && (Log() << Verbose(1) << "Factor s is " << temp1.ScalarProduct(&temp2) << "/" << temp2.NormSquared() << " = " << s << "." << endl);427 428 // construct intersection429 CopyVector(&a);430 Scale(s);431 AddVector(Line1a);432 DoLog(1) && (Log() << Verbose(1) << "Intersection is at " << *this << "." << endl);433 434 return true;435 266 }; 436 267 … … 438 269 * \param *y array to second vector 439 270 */ 440 void Vector::ProjectIt(const Vector * const y) 441 { 442 Vector helper(*y); 443 helper.Scale(-(ScalarProduct(y))); 444 AddVector(&helper); 271 void Vector::ProjectIt(const Vector &y) 272 { 273 (*this) += (-ScalarProduct(y))*y; 445 274 }; 446 275 … … 449 278 * \return Vector 450 279 */ 451 Vector Vector::Projection(const Vector * consty) const452 { 453 Vector helper (*y);454 helper.Scale((ScalarProduct(y)/y ->NormSquared()));280 Vector Vector::Projection(const Vector &y) const 281 { 282 Vector helper = y; 283 helper.Scale((ScalarProduct(y)/y.NormSquared())); 455 284 456 285 return helper; … … 462 291 double Vector::Norm() const 463 292 { 464 double res = 0.; 465 for (int i=NDIM;i--;) 466 res += this->x[i]*this->x[i]; 467 return (sqrt(res)); 293 return (sqrt(NormSquared())); 468 294 }; 469 295 … … 473 299 double Vector::NormSquared() const 474 300 { 475 return (ScalarProduct( this));301 return (ScalarProduct(*this)); 476 302 }; 477 303 … … 480 306 void Vector::Normalize() 481 307 { 482 double res = 0.; 483 for (int i=NDIM;i--;) 484 res += this->x[i]*this->x[i]; 485 if (fabs(res) > MYEPSILON) 486 res = 1./sqrt(res); 487 Scale(&res); 308 double factor = Norm(); 309 (*this) *= 1/factor; 488 310 }; 489 311 … … 492 314 void Vector::Zero() 493 315 { 494 for (int i=NDIM;i--;) 495 this->x[i] = 0.; 316 at(0)=at(1)=at(2)=0; 496 317 }; 497 318 … … 500 321 void Vector::One(const double one) 501 322 { 502 for (int i=NDIM;i--;) 503 this->x[i] = one; 504 }; 505 506 /** Initialises all components of this vector. 507 */ 508 void Vector::Init(const double x1, const double x2, const double x3) 509 { 510 x[0] = x1; 511 x[1] = x2; 512 x[2] = x3; 323 at(0)=at(1)=at(2)=one; 513 324 }; 514 325 … … 532 343 * @return true - vector is normalized, false - vector is not 533 344 */ 534 bool Vector::IsNormalTo(const Vector * constnormal) const345 bool Vector::IsNormalTo(const Vector &normal) const 535 346 { 536 347 if (ScalarProduct(normal) < MYEPSILON) … … 543 354 * @return true - vector is normalized, false - vector is not 544 355 */ 545 bool Vector::IsEqualTo(const Vector * consta) const356 bool Vector::IsEqualTo(const Vector &a) const 546 357 { 547 358 bool status = true; 548 359 for (int i=0;i<NDIM;i++) { 549 if (fabs(x[i] - a ->x[i]) > MYEPSILON)360 if (fabs(x[i] - a[i]) > MYEPSILON) 550 361 status = false; 551 362 } … … 557 368 * \return \f$\acos\bigl(frac{\langle x, y \rangle}{|x||y|}\bigr)\f$ 558 369 */ 559 double Vector::Angle(const Vector * consty) const560 { 561 double norm1 = Norm(), norm2 = y ->Norm();370 double Vector::Angle(const Vector &y) const 371 { 372 double norm1 = Norm(), norm2 = y.Norm(); 562 373 double angle = -1; 563 374 if ((fabs(norm1) > MYEPSILON) && (fabs(norm2) > MYEPSILON)) … … 572 383 }; 573 384 574 /** Rotates the vector relative to the origin around the axis given by \a *axis by an angle of \a alpha. 575 * \param *axis rotation axis 576 * \param alpha rotation angle in radian 577 */ 578 void Vector::RotateVector(const Vector * const axis, const double alpha) 579 { 580 Vector a,y; 581 // normalise this vector with respect to axis 582 a.CopyVector(this); 583 a.ProjectOntoPlane(axis); 584 // construct normal vector 585 bool rotatable = y.MakeNormalVector(axis,&a); 586 // The normal vector cannot be created if there is linar dependency. 587 // Then the vector to rotate is on the axis and any rotation leads to the vector itself. 588 if (!rotatable) { 589 return; 590 } 591 y.Scale(Norm()); 592 // scale normal vector by sine and this vector by cosine 593 y.Scale(sin(alpha)); 594 a.Scale(cos(alpha)); 595 CopyVector(Projection(axis)); 596 // add scaled normal vector onto this vector 597 AddVector(&y); 598 // add part in axis direction 599 AddVector(&a); 600 }; 385 386 double& Vector::operator[](size_t i){ 387 ASSERT(i<=NDIM && i>=0,"Vector Index out of Range"); 388 return x[i]; 389 } 390 391 const double& Vector::operator[](size_t i) const{ 392 ASSERT(i<=NDIM && i>=0,"Vector Index out of Range"); 393 return x[i]; 394 } 395 396 double& Vector::at(size_t i){ 397 return (*this)[i]; 398 } 399 400 const double& Vector::at(size_t i) const{ 401 return (*this)[i]; 402 } 403 404 double* Vector::get(){ 405 return x; 406 } 601 407 602 408 /** Compares vector \a to vector \a b component-wise. … … 605 411 * \return a == b 606 412 */ 607 bool operator==(const Vector& a, const Vector& b) 608 { 609 bool status = true; 610 for (int i=0;i<NDIM;i++) 611 status = status && (fabs(a.x[i] - b.x[i]) < MYEPSILON); 612 return status; 413 bool Vector::operator==(const Vector& b) const 414 { 415 return IsEqualTo(b); 613 416 }; 614 417 … … 618 421 * \return lhs + a 619 422 */ 620 const Vector& operator+=(Vector& a,const Vector& b)621 { 622 a.AddVector(&b);623 return a;423 const Vector& Vector::operator+=(const Vector& b) 424 { 425 this->AddVector(b); 426 return *this; 624 427 }; 625 428 … … 629 432 * \return lhs - a 630 433 */ 631 const Vector& operator-=(Vector& a,const Vector& b)632 { 633 a.SubtractVector(&b);634 return a;434 const Vector& Vector::operator-=(const Vector& b) 435 { 436 this->SubtractVector(b); 437 return *this; 635 438 }; 636 439 … … 651 454 * \return a + b 652 455 */ 653 Vector const operator+(const Vector& a, const Vector& b)654 { 655 Vector x (a);656 x.AddVector( &b);456 Vector const Vector::operator+(const Vector& b) const 457 { 458 Vector x = *this; 459 x.AddVector(b); 657 460 return x; 658 461 }; … … 663 466 * \return a - b 664 467 */ 665 Vector const operator-(const Vector& a, const Vector& b)666 { 667 Vector x (a);668 x.SubtractVector( &b);468 Vector const Vector::operator-(const Vector& b) const 469 { 470 Vector x = *this; 471 x.SubtractVector(b); 669 472 return x; 670 473 }; … … 694 497 }; 695 498 696 /** Prints a 3dim vector.697 * prints no end of line.698 */699 void Vector::Output() const700 {701 DoLog(0) && (Log() << Verbose(0) << "(");702 for (int i=0;i<NDIM;i++) {703 DoLog(0) && (Log() << Verbose(0) << x[i]);704 if (i != 2)705 DoLog(0) && (Log() << Verbose(0) << ",");706 }707 DoLog(0) && (Log() << Verbose(0) << ")");708 };709 710 499 ostream& operator<<(ostream& ost, const Vector& m) 711 500 { 712 501 ost << "("; 713 502 for (int i=0;i<NDIM;i++) { 714 ost << m .x[i];503 ost << m[i]; 715 504 if (i != 2) 716 505 ost << ","; … … 720 509 }; 721 510 722 /** Scales each atom coordinate by an individual \a factor. 723 * \param *factor pointer to scaling factor 724 */ 725 void Vector::Scale(const double ** const factor) 511 512 void Vector::ScaleAll(const double *factor) 726 513 { 727 514 for (int i=NDIM;i--;) 728 x[i] *= (*factor)[i]; 729 }; 730 731 void Vector::Scale(const double * const factor) 732 { 733 for (int i=NDIM;i--;) 734 x[i] *= *factor; 735 }; 515 x[i] *= factor[i]; 516 }; 517 518 736 519 737 520 void Vector::Scale(const double factor) … … 739 522 for (int i=NDIM;i--;) 740 523 x[i] *= factor; 741 };742 743 /** Translate atom by given vector.744 * \param trans[] translation vector.745 */746 void Vector::Translate(const Vector * const trans)747 {748 for (int i=NDIM;i--;)749 x[i] += trans->x[i];750 524 }; 751 525 … … 773 547 void Vector::MatrixMultiplication(const double * const M) 774 548 { 775 Vector C;776 549 // do the matrix multiplication 777 C.x[0] = M[0]*x[0]+M[3]*x[1]+M[6]*x[2]; 778 C.x[1] = M[1]*x[0]+M[4]*x[1]+M[7]*x[2]; 779 C.x[2] = M[2]*x[0]+M[5]*x[1]+M[8]*x[2]; 780 // transfer the result into this 781 for (int i=NDIM;i--;) 782 x[i] = C.x[i]; 550 at(0) = M[0]*x[0]+M[3]*x[1]+M[6]*x[2]; 551 at(1) = M[1]*x[0]+M[4]*x[1]+M[7]*x[2]; 552 at(2) = M[2]*x[0]+M[5]*x[1]+M[8]*x[2]; 783 553 }; 784 554 … … 786 556 * \param *matrix NDIM_NDIM array 787 557 */ 788 void Vector::InverseMatrixMultiplication(const double * const A) 789 { 790 Vector C; 558 bool Vector::InverseMatrixMultiplication(const double * const A) 559 { 791 560 double B[NDIM*NDIM]; 792 561 double detA = RDET3(A); … … 807 576 808 577 // do the matrix multiplication 809 C.x[0] = B[0]*x[0]+B[3]*x[1]+B[6]*x[2]; 810 C.x[1] = B[1]*x[0]+B[4]*x[1]+B[7]*x[2]; 811 C.x[2] = B[2]*x[0]+B[5]*x[1]+B[8]*x[2]; 812 // transfer the result into this 813 for (int i=NDIM;i--;) 814 x[i] = C.x[i]; 578 at(0) = B[0]*x[0]+B[3]*x[1]+B[6]*x[2]; 579 at(1) = B[1]*x[0]+B[4]*x[1]+B[7]*x[2]; 580 at(2) = B[2]*x[0]+B[5]*x[1]+B[8]*x[2]; 581 582 return true; 815 583 } else { 816 DoeLog(1) && (eLog()<< Verbose(1) << "inverse of matrix does not exists: det A = " << detA << "." << endl);584 return false; 817 585 } 818 586 }; … … 826 594 * \param *factors three-component vector with the factor for each given vector 827 595 */ 828 void Vector::LinearCombinationOfVectors(const Vector * const x1, const Vector * const x2, const Vector * const x3, const double * const factors) 829 { 830 for(int i=NDIM;i--;) 831 x[i] = factors[0]*x1->x[i] + factors[1]*x2->x[i] + factors[2]*x3->x[i]; 596 void Vector::LinearCombinationOfVectors(const Vector &x1, const Vector &x2, const Vector &x3, const double * const factors) 597 { 598 (*this) = (factors[0]*x1) + 599 (factors[1]*x2) + 600 (factors[2]*x3); 832 601 }; 833 602 … … 835 604 * \param n[] normal vector of mirror plane. 836 605 */ 837 void Vector::Mirror(const Vector * constn)606 void Vector::Mirror(const Vector &n) 838 607 { 839 608 double projection; 840 projection = ScalarProduct(n)/n ->ScalarProduct(n); // remove constancy from n (keep as logical one)609 projection = ScalarProduct(n)/n.NormSquared(); // remove constancy from n (keep as logical one) 841 610 // withdraw projected vector twice from original one 842 DoLog(1) && (Log() << Verbose(1) << "Vector: ");843 Output();844 DoLog(0) && (Log() << Verbose(0) << "\t");845 611 for (int i=NDIM;i--;) 846 x[i] -= 2.*projection*n->x[i]; 847 DoLog(0) && (Log() << Verbose(0) << "Projected vector: "); 848 Output(); 849 DoLog(0) && (Log() << Verbose(0) << endl); 850 }; 851 852 /** Calculates normal vector for three given vectors (being three points in space). 853 * Makes this vector orthonormal to the three given points, making up a place in 3d space. 854 * \param *y1 first vector 855 * \param *y2 second vector 856 * \param *y3 third vector 857 * \return true - success, vectors are linear independent, false - failure due to linear dependency 858 */ 859 bool Vector::MakeNormalVector(const Vector * const y1, const Vector * const y2, const Vector * const y3) 860 { 861 Vector x1, x2; 862 863 x1.CopyVector(y1); 864 x1.SubtractVector(y2); 865 x2.CopyVector(y3); 866 x2.SubtractVector(y2); 867 if ((fabs(x1.Norm()) < MYEPSILON) || (fabs(x2.Norm()) < MYEPSILON) || (fabs(x1.Angle(&x2)) < MYEPSILON)) { 868 DoeLog(2) && (eLog()<< Verbose(2) << "Given vectors are linear dependent." << endl); 869 return false; 870 } 871 // Log() << Verbose(4) << "relative, first plane coordinates:"; 872 // x1.Output((ofstream *)&cout); 873 // Log() << Verbose(0) << endl; 874 // Log() << Verbose(4) << "second plane coordinates:"; 875 // x2.Output((ofstream *)&cout); 876 // Log() << Verbose(0) << endl; 877 878 this->x[0] = (x1.x[1]*x2.x[2] - x1.x[2]*x2.x[1]); 879 this->x[1] = (x1.x[2]*x2.x[0] - x1.x[0]*x2.x[2]); 880 this->x[2] = (x1.x[0]*x2.x[1] - x1.x[1]*x2.x[0]); 881 Normalize(); 882 883 return true; 884 }; 885 886 887 /** Calculates orthonormal vector to two given vectors. 888 * Makes this vector orthonormal to two given vectors. This is very similar to the other 889 * vector::MakeNormalVector(), only there three points whereas here two difference 890 * vectors are given. 891 * \param *x1 first vector 892 * \param *x2 second vector 893 * \return true - success, vectors are linear independent, false - failure due to linear dependency 894 */ 895 bool Vector::MakeNormalVector(const Vector * const y1, const Vector * const y2) 896 { 897 Vector x1,x2; 898 x1.CopyVector(y1); 899 x2.CopyVector(y2); 900 Zero(); 901 if ((fabs(x1.Norm()) < MYEPSILON) || (fabs(x2.Norm()) < MYEPSILON) || (fabs(x1.Angle(&x2)) < MYEPSILON)) { 902 DoeLog(2) && (eLog()<< Verbose(2) << "Given vectors are linear dependent." << endl); 903 return false; 904 } 905 // Log() << Verbose(4) << "relative, first plane coordinates:"; 906 // x1.Output((ofstream *)&cout); 907 // Log() << Verbose(0) << endl; 908 // Log() << Verbose(4) << "second plane coordinates:"; 909 // x2.Output((ofstream *)&cout); 910 // Log() << Verbose(0) << endl; 911 912 this->x[0] = (x1.x[1]*x2.x[2] - x1.x[2]*x2.x[1]); 913 this->x[1] = (x1.x[2]*x2.x[0] - x1.x[0]*x2.x[2]); 914 this->x[2] = (x1.x[0]*x2.x[1] - x1.x[1]*x2.x[0]); 915 Normalize(); 916 917 return true; 612 at(i) -= 2.*projection*n[i]; 918 613 }; 919 614 … … 924 619 * \return true - success, false - vector is zero 925 620 */ 926 bool Vector::MakeNormal Vector(const Vector * consty1)621 bool Vector::MakeNormalTo(const Vector &y1) 927 622 { 928 623 bool result = false; 929 double factor = y1 ->ScalarProduct(this)/y1->NormSquared();624 double factor = y1.ScalarProduct(*this)/y1.NormSquared(); 930 625 Vector x1; 931 x1.CopyVector(y1); 932 x1.Scale(factor); 933 SubtractVector(&x1); 626 x1 = factor * y1; 627 SubtractVector(x1); 934 628 for (int i=NDIM;i--;) 935 629 result = result || (fabs(x[i]) > MYEPSILON); … … 944 638 * \return true - success, false - failure (null vector given) 945 639 */ 946 bool Vector::GetOneNormalVector(const Vector * constGivenVector)640 bool Vector::GetOneNormalVector(const Vector &GivenVector) 947 641 { 948 642 int Components[NDIM]; // contains indices of non-zero components … … 951 645 double norm; 952 646 953 DoLog(4) && (Log() << Verbose(4));954 GivenVector->Output();955 DoLog(0) && (Log() << Verbose(0) << endl);956 647 for (j=NDIM;j--;) 957 648 Components[j] = -1; 958 649 // find two components != 0 959 650 for (j=0;j<NDIM;j++) 960 if (fabs(GivenVector ->x[j]) > MYEPSILON)651 if (fabs(GivenVector[j]) > MYEPSILON) 961 652 Components[Last++] = j; 962 DoLog(4) && (Log() << Verbose(4) << Last << " Components != 0: (" << Components[0] << "," << Components[1] << "," << Components[2] << ")" << endl);963 653 964 654 switch(Last) { 965 655 case 3: // threecomponent system 966 656 case 2: // two component system 967 norm = sqrt(1./(GivenVector ->x[Components[1]]*GivenVector->x[Components[1]]) + 1./(GivenVector->x[Components[0]]*GivenVector->x[Components[0]]));657 norm = sqrt(1./(GivenVector[Components[1]]*GivenVector[Components[1]]) + 1./(GivenVector[Components[0]]*GivenVector[Components[0]])); 968 658 x[Components[2]] = 0.; 969 659 // in skp both remaining parts shall become zero but with opposite sign and third is zero 970 x[Components[1]] = -1./GivenVector ->x[Components[1]] / norm;971 x[Components[0]] = 1./GivenVector ->x[Components[0]] / norm;660 x[Components[1]] = -1./GivenVector[Components[1]] / norm; 661 x[Components[0]] = 1./GivenVector[Components[0]] / norm; 972 662 return true; 973 663 break; … … 984 674 }; 985 675 986 /** Determines parameter needed to multiply this vector to obtain intersection point with plane defined by \a *A, \a *B and \a *C.987 * \param *A first plane vector988 * \param *B second plane vector989 * \param *C third plane vector990 * \return scaling parameter for this vector991 */992 double Vector::CutsPlaneAt(const Vector * const A, const Vector * const B, const Vector * const C) const993 {994 // Log() << Verbose(3) << "For comparison: ";995 // Log() << Verbose(0) << "A " << A->Projection(this) << "\t";996 // Log() << Verbose(0) << "B " << B->Projection(this) << "\t";997 // Log() << Verbose(0) << "C " << C->Projection(this) << "\t";998 // Log() << Verbose(0) << endl;999 return A->ScalarProduct(this);1000 };1001 1002 /** Creates a new vector as the one with least square distance to a given set of \a vectors.1003 * \param *vectors set of vectors1004 * \param num number of vectors1005 * \return true if success, false if failed due to linear dependency1006 */1007 bool Vector::LSQdistance(const Vector **vectors, int num)1008 {1009 int j;1010 1011 for (j=0;j<num;j++) {1012 DoLog(1) && (Log() << Verbose(1) << j << "th atom's vector: ");1013 (vectors[j])->Output();1014 DoLog(0) && (Log() << Verbose(0) << endl);1015 }1016 1017 int np = 3;1018 struct LSQ_params par;1019 1020 const gsl_multimin_fminimizer_type *T =1021 gsl_multimin_fminimizer_nmsimplex;1022 gsl_multimin_fminimizer *s = NULL;1023 gsl_vector *ss, *y;1024 gsl_multimin_function minex_func;1025 1026 size_t iter = 0, i;1027 int status;1028 double size;1029 1030 /* Initial vertex size vector */1031 ss = gsl_vector_alloc (np);1032 y = gsl_vector_alloc (np);1033 1034 /* Set all step sizes to 1 */1035 gsl_vector_set_all (ss, 1.0);1036 1037 /* Starting point */1038 par.vectors = vectors;1039 par.num = num;1040 1041 for (i=NDIM;i--;)1042 gsl_vector_set(y, i, (vectors[0]->x[i] - vectors[1]->x[i])/2.);1043 1044 /* Initialize method and iterate */1045 minex_func.f = &LSQ;1046 minex_func.n = np;1047 minex_func.params = (void *)∥1048 1049 s = gsl_multimin_fminimizer_alloc (T, np);1050 gsl_multimin_fminimizer_set (s, &minex_func, y, ss);1051 1052 do1053 {1054 iter++;1055 status = gsl_multimin_fminimizer_iterate(s);1056 1057 if (status)1058 break;1059 1060 size = gsl_multimin_fminimizer_size (s);1061 status = gsl_multimin_test_size (size, 1e-2);1062 1063 if (status == GSL_SUCCESS)1064 {1065 printf ("converged to minimum at\n");1066 }1067 1068 printf ("%5d ", (int)iter);1069 for (i = 0; i < (size_t)np; i++)1070 {1071 printf ("%10.3e ", gsl_vector_get (s->x, i));1072 }1073 printf ("f() = %7.3f size = %.3f\n", s->fval, size);1074 }1075 while (status == GSL_CONTINUE && iter < 100);1076 1077 for (i=(size_t)np;i--;)1078 this->x[i] = gsl_vector_get(s->x, i);1079 gsl_vector_free(y);1080 gsl_vector_free(ss);1081 gsl_multimin_fminimizer_free (s);1082 1083 return true;1084 };1085 1086 676 /** Adds vector \a *y componentwise. 1087 677 * \param *y vector 1088 678 */ 1089 void Vector::AddVector(const Vector * consty)1090 { 1091 for (int i=NDIM;i--;)1092 this->x[i] += y->x[i];679 void Vector::AddVector(const Vector &y) 680 { 681 for(int i=NDIM;i--;) 682 x[i] += y[i]; 1093 683 } 1094 684 … … 1096 686 * \param *y vector 1097 687 */ 1098 void Vector::SubtractVector(const Vector * const y) 1099 { 1100 for (int i=NDIM;i--;) 1101 this->x[i] -= y->x[i]; 1102 } 1103 1104 /** Copy vector \a *y componentwise. 1105 * \param *y vector 1106 */ 1107 void Vector::CopyVector(const Vector * const y) 1108 { 1109 // check for self assignment 1110 if(y!=this){ 1111 for (int i=NDIM;i--;) 1112 this->x[i] = y->x[i]; 1113 } 1114 } 1115 1116 /** Copy vector \a y componentwise. 1117 * \param y vector 1118 */ 1119 void Vector::CopyVector(const Vector &y) 1120 { 1121 // check for self assignment 1122 if(&y!=this) { 1123 for (int i=NDIM;i--;) 1124 this->x[i] = y.x[i]; 1125 } 1126 } 1127 1128 1129 /** Asks for position, checks for boundary. 1130 * \param cell_size unitary size of cubic cell, coordinates must be within 0...cell_size 1131 * \param check whether bounds shall be checked (true) or not (false) 1132 */ 1133 void Vector::AskPosition(const double * const cell_size, const bool check) 1134 { 1135 char coords[3] = {'x','y','z'}; 1136 int j = -1; 1137 for (int i=0;i<3;i++) { 1138 j += i+1; 1139 do { 1140 DoLog(0) && (Log() << Verbose(0) << coords[i] << "[0.." << cell_size[j] << "]: "); 1141 cin >> x[i]; 1142 } while (((x[i] < 0) || (x[i] >= cell_size[j])) && (check)); 1143 } 1144 }; 1145 1146 /** Solves a vectorial system consisting of two orthogonal statements and a norm statement. 1147 * This is linear system of equations to be solved, however of the three given (skp of this vector\ 1148 * with either of the three hast to be zero) only two are linear independent. The third equation 1149 * is that the vector should be of magnitude 1 (orthonormal). This all leads to a case-based solution 1150 * where very often it has to be checked whether a certain value is zero or not and thus forked into 1151 * another case. 1152 * \param *x1 first vector 1153 * \param *x2 second vector 1154 * \param *y third vector 1155 * \param alpha first angle 1156 * \param beta second angle 1157 * \param c norm of final vector 1158 * \return a vector with \f$\langle x1,x2 \rangle=A\f$, \f$\langle x1,y \rangle = B\f$ and with norm \a c. 1159 * \bug this is not yet working properly 1160 */ 1161 bool Vector::SolveSystem(Vector * x1, Vector * x2, Vector * y, const double alpha, const double beta, const double c) 1162 { 1163 double D1,D2,D3,E1,E2,F1,F2,F3,p,q=0., A, B1, B2, C; 1164 double ang; // angle on testing 1165 double sign[3]; 1166 int i,j,k; 1167 A = cos(alpha) * x1->Norm() * c; 1168 B1 = cos(beta + M_PI/2.) * y->Norm() * c; 1169 B2 = cos(beta) * x2->Norm() * c; 1170 C = c * c; 1171 DoLog(2) && (Log() << Verbose(2) << "A " << A << "\tB " << B1 << "\tC " << C << endl); 1172 int flag = 0; 1173 if (fabs(x1->x[0]) < MYEPSILON) { // check for zero components for the later flipping and back-flipping 1174 if (fabs(x1->x[1]) > MYEPSILON) { 1175 flag = 1; 1176 } else if (fabs(x1->x[2]) > MYEPSILON) { 1177 flag = 2; 1178 } else { 1179 return false; 1180 } 1181 } 1182 switch (flag) { 1183 default: 1184 case 0: 1185 break; 1186 case 2: 1187 flip(x1->x[0],x1->x[1]); 1188 flip(x2->x[0],x2->x[1]); 1189 flip(y->x[0],y->x[1]); 1190 //flip(x[0],x[1]); 1191 flip(x1->x[1],x1->x[2]); 1192 flip(x2->x[1],x2->x[2]); 1193 flip(y->x[1],y->x[2]); 1194 //flip(x[1],x[2]); 1195 case 1: 1196 flip(x1->x[0],x1->x[1]); 1197 flip(x2->x[0],x2->x[1]); 1198 flip(y->x[0],y->x[1]); 1199 //flip(x[0],x[1]); 1200 flip(x1->x[1],x1->x[2]); 1201 flip(x2->x[1],x2->x[2]); 1202 flip(y->x[1],y->x[2]); 1203 //flip(x[1],x[2]); 1204 break; 1205 } 1206 // now comes the case system 1207 D1 = -y->x[0]/x1->x[0]*x1->x[1]+y->x[1]; 1208 D2 = -y->x[0]/x1->x[0]*x1->x[2]+y->x[2]; 1209 D3 = y->x[0]/x1->x[0]*A-B1; 1210 DoLog(2) && (Log() << Verbose(2) << "D1 " << D1 << "\tD2 " << D2 << "\tD3 " << D3 << "\n"); 1211 if (fabs(D1) < MYEPSILON) { 1212 DoLog(2) && (Log() << Verbose(2) << "D1 == 0!\n"); 1213 if (fabs(D2) > MYEPSILON) { 1214 DoLog(3) && (Log() << Verbose(3) << "D2 != 0!\n"); 1215 x[2] = -D3/D2; 1216 E1 = A/x1->x[0] + x1->x[2]/x1->x[0]*D3/D2; 1217 E2 = -x1->x[1]/x1->x[0]; 1218 DoLog(3) && (Log() << Verbose(3) << "E1 " << E1 << "\tE2 " << E2 << "\n"); 1219 F1 = E1*E1 + 1.; 1220 F2 = -E1*E2; 1221 F3 = E1*E1 + D3*D3/(D2*D2) - C; 1222 DoLog(3) && (Log() << Verbose(3) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n"); 1223 if (fabs(F1) < MYEPSILON) { 1224 DoLog(4) && (Log() << Verbose(4) << "F1 == 0!\n"); 1225 DoLog(4) && (Log() << Verbose(4) << "Gleichungssystem linear\n"); 1226 x[1] = F3/(2.*F2); 1227 } else { 1228 p = F2/F1; 1229 q = p*p - F3/F1; 1230 DoLog(4) && (Log() << Verbose(4) << "p " << p << "\tq " << q << endl); 1231 if (q < 0) { 1232 DoLog(4) && (Log() << Verbose(4) << "q < 0" << endl); 1233 return false; 1234 } 1235 x[1] = p + sqrt(q); 1236 } 1237 x[0] = A/x1->x[0] - x1->x[1]/x1->x[0]*x[1] + x1->x[2]/x1->x[0]*x[2]; 1238 } else { 1239 DoLog(2) && (Log() << Verbose(2) << "Gleichungssystem unterbestimmt\n"); 1240 return false; 1241 } 1242 } else { 1243 E1 = A/x1->x[0]+x1->x[1]/x1->x[0]*D3/D1; 1244 E2 = x1->x[1]/x1->x[0]*D2/D1 - x1->x[2]; 1245 DoLog(2) && (Log() << Verbose(2) << "E1 " << E1 << "\tE2 " << E2 << "\n"); 1246 F1 = E2*E2 + D2*D2/(D1*D1) + 1.; 1247 F2 = -(E1*E2 + D2*D3/(D1*D1)); 1248 F3 = E1*E1 + D3*D3/(D1*D1) - C; 1249 DoLog(2) && (Log() << Verbose(2) << "F1 " << F1 << "\tF2 " << F2 << "\tF3 " << F3 << "\n"); 1250 if (fabs(F1) < MYEPSILON) { 1251 DoLog(3) && (Log() << Verbose(3) << "F1 == 0!\n"); 1252 DoLog(3) && (Log() << Verbose(3) << "Gleichungssystem linear\n"); 1253 x[2] = F3/(2.*F2); 1254 } else { 1255 p = F2/F1; 1256 q = p*p - F3/F1; 1257 DoLog(3) && (Log() << Verbose(3) << "p " << p << "\tq " << q << endl); 1258 if (q < 0) { 1259 DoLog(3) && (Log() << Verbose(3) << "q < 0" << endl); 1260 return false; 1261 } 1262 x[2] = p + sqrt(q); 1263 } 1264 x[1] = (-D2 * x[2] - D3)/D1; 1265 x[0] = A/x1->x[0] - x1->x[1]/x1->x[0]*x[1] + x1->x[2]/x1->x[0]*x[2]; 1266 } 1267 switch (flag) { // back-flipping 1268 default: 1269 case 0: 1270 break; 1271 case 2: 1272 flip(x1->x[0],x1->x[1]); 1273 flip(x2->x[0],x2->x[1]); 1274 flip(y->x[0],y->x[1]); 1275 flip(x[0],x[1]); 1276 flip(x1->x[1],x1->x[2]); 1277 flip(x2->x[1],x2->x[2]); 1278 flip(y->x[1],y->x[2]); 1279 flip(x[1],x[2]); 1280 case 1: 1281 flip(x1->x[0],x1->x[1]); 1282 flip(x2->x[0],x2->x[1]); 1283 flip(y->x[0],y->x[1]); 1284 //flip(x[0],x[1]); 1285 flip(x1->x[1],x1->x[2]); 1286 flip(x2->x[1],x2->x[2]); 1287 flip(y->x[1],y->x[2]); 1288 flip(x[1],x[2]); 1289 break; 1290 } 1291 // one z component is only determined by its radius (without sign) 1292 // thus check eight possible sign flips and determine by checking angle with second vector 1293 for (i=0;i<8;i++) { 1294 // set sign vector accordingly 1295 for (j=2;j>=0;j--) { 1296 k = (i & pot(2,j)) << j; 1297 DoLog(2) && (Log() << Verbose(2) << "k " << k << "\tpot(2,j) " << pot(2,j) << endl); 1298 sign[j] = (k == 0) ? 1. : -1.; 1299 } 1300 DoLog(2) && (Log() << Verbose(2) << i << ": sign matrix is " << sign[0] << "\t" << sign[1] << "\t" << sign[2] << "\n"); 1301 // apply sign matrix 1302 for (j=NDIM;j--;) 1303 x[j] *= sign[j]; 1304 // calculate angle and check 1305 ang = x2->Angle (this); 1306 DoLog(1) && (Log() << Verbose(1) << i << "th angle " << ang << "\tbeta " << cos(beta) << " :\t"); 1307 if (fabs(ang - cos(beta)) < MYEPSILON) { 1308 break; 1309 } 1310 // unapply sign matrix (is its own inverse) 1311 for (j=NDIM;j--;) 1312 x[j] *= sign[j]; 1313 } 1314 return true; 1315 }; 688 void Vector::SubtractVector(const Vector &y) 689 { 690 for(int i=NDIM;i--;) 691 x[i] -= y[i]; 692 } 1316 693 1317 694 /** … … 1324 701 bool Vector::IsInParallelepiped(const Vector &offset, const double * const parallelepiped) const 1325 702 { 1326 Vector a; 1327 a.CopyVector(this); 1328 a.SubtractVector(&offset); 703 Vector a = (*this)-offset; 1329 704 a.InverseMatrixMultiplication(parallelepiped); 1330 705 bool isInside = true; 1331 706 1332 707 for (int i=NDIM;i--;) 1333 isInside = isInside && ((a .x[i] <= 1) && (a.x[i] >= 0));708 isInside = isInside && ((a[i] <= 1) && (a[i] >= 0)); 1334 709 1335 710 return isInside;
Note:
See TracChangeset
for help on using the changeset viewer.
