00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include <new>
00047
00048 #include "Math3d.h"
00049 #include "Helpers/BasicFileIO.h"
00050
00051 #include <math.h>
00052
00053
00054
00055
00056
00057
00058
00059 const Vec3d Math3d::zero_vec = { 0, 0, 0 };
00060 const Mat3d Math3d::unit_mat = { 1, 0, 0, 0, 1, 0, 0, 0, 1 };
00061 const Mat3d Math3d::zero_mat = { 0, 0, 0, 0, 0, 0, 0, 0 ,0 };
00062
00063
00064
00065
00066
00067
00068 bool Math3d::LoadFromFile(Vec3d &vector, const char *pFilePath)
00069 {
00070
00071 FILE *f = fopen(pFilePath, "r");
00072 if (!f)
00073 return false;
00074
00075 const int nFileSize = CBasicFileIO::GetFileSize(f);
00076
00077 if (nFileSize > 1024)
00078 {
00079 fclose(f);
00080 return false;
00081 }
00082
00083 char *pBuffer = new char[nFileSize];
00084 if (fread(pBuffer, nFileSize, 1, f) != 1)
00085 {
00086 fclose(f);
00087 delete [] pBuffer;
00088 return false;
00089 }
00090
00091 fclose(f);
00092
00093 if (sscanf(pBuffer, "%f%f%f", &vector.x, &vector.y, &vector.z) != 3)
00094 {
00095 delete [] pBuffer;
00096 return false;
00097 }
00098
00099 delete [] pBuffer;
00100
00101 return true;
00102 }
00103
00104 bool Math3d::LoadFromFile(Mat3d &matrix, const char *pFilePath)
00105 {
00106
00107 FILE *f = fopen(pFilePath, "r");
00108 if (!f)
00109 return false;
00110
00111 const int nFileSize = CBasicFileIO::GetFileSize(f);
00112
00113 if (nFileSize > 1024)
00114 {
00115 fclose(f);
00116 return false;
00117 }
00118
00119 char *pBuffer = new char[nFileSize];
00120 if (fread(pBuffer, nFileSize, 1, f) != 1)
00121 {
00122 fclose(f);
00123 delete [] pBuffer;
00124 return false;
00125 }
00126
00127 fclose(f);
00128
00129 if (sscanf(pBuffer, "%f%f%f%f%f%f%f%f%f",
00130 &matrix.r1, &matrix.r2, &matrix.r3,
00131 &matrix.r4, &matrix.r5, &matrix.r6,
00132 &matrix.r7, &matrix.r8, &matrix.r9) != 9)
00133 {
00134 delete [] pBuffer;
00135 return false;
00136 }
00137
00138 delete [] pBuffer;
00139
00140 return true;
00141 }
00142
00143 bool Math3d::LoadFromFile(Transformation3d &transformation, const char *pFilePath)
00144 {
00145
00146 FILE *f = fopen(pFilePath, "r");
00147 if (!f)
00148 return false;
00149
00150 const int nFileSize = CBasicFileIO::GetFileSize(f);
00151
00152 if (nFileSize > 1024)
00153 {
00154 fclose(f);
00155 return false;
00156 }
00157
00158 char *pBuffer = new char[nFileSize];
00159 if (fread(pBuffer, nFileSize, 1, f) != 1)
00160 {
00161 fclose(f);
00162 delete [] pBuffer;
00163 return false;
00164 }
00165
00166 fclose(f);
00167
00168 if (sscanf(pBuffer, "%f%f%f%f%f%f%f%f%f%f%f%f",
00169 &transformation.rotation.r1, &transformation.rotation.r2, &transformation.rotation.r3,
00170 &transformation.rotation.r4, &transformation.rotation.r5, &transformation.rotation.r6,
00171 &transformation.rotation.r7, &transformation.rotation.r8, &transformation.rotation.r9,
00172 &transformation.translation.x, &transformation.translation.y, &transformation.translation.z) != 12)
00173 {
00174 delete [] pBuffer;
00175 return false;
00176 }
00177
00178 delete [] pBuffer;
00179
00180 return true;
00181 }
00182
00183 bool Math3d::SaveToFile(const Vec3d &vector, const char *pFilePath)
00184 {
00185 FILE *f = fopen(pFilePath, "w");
00186 if (!f)
00187 return false;
00188
00189 if (fprintf(f, "%.10f %.10f %.10f", vector.x, vector.y, vector.z) <= 0)
00190 {
00191 fclose(f);
00192 return false;
00193 }
00194
00195 fclose(f);
00196
00197 return true;
00198 }
00199
00200 bool Math3d::SaveToFile(const Mat3d &matrix, const char *pFilePath)
00201 {
00202 FILE *f = fopen(pFilePath, "w");
00203 if (!f)
00204 return false;
00205
00206 if (fprintf(f, "%.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f",
00207 matrix.r1, matrix.r2, matrix.r3,
00208 matrix.r4, matrix.r5, matrix.r6,
00209 matrix.r7, matrix.r8, matrix.r9) <= 0)
00210 {
00211 fclose(f);
00212 return false;
00213 }
00214
00215 fclose(f);
00216
00217 return true;
00218 }
00219
00220 bool Math3d::SaveToFile(const Transformation3d &transformation, const char *pFilePath)
00221 {
00222 FILE *f = fopen(pFilePath, "w");
00223 if (!f)
00224 return false;
00225
00226 if (fprintf(f, "%.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f\n%.10f %.10f %.10f",
00227 transformation.rotation.r1, transformation.rotation.r2, transformation.rotation.r3,
00228 transformation.rotation.r4, transformation.rotation.r5, transformation.rotation.r6,
00229 transformation.rotation.r7, transformation.rotation.r8, transformation.rotation.r9,
00230 transformation.translation.x, transformation.translation.y, transformation.translation.z) <= 0)
00231 {
00232 fclose(f);
00233 return false;
00234 }
00235
00236 fclose(f);
00237
00238 return true;
00239 }
00240
00241
00242
00243 void Math3d::SetVec(Vec3d &vec, float x, float y, float z)
00244 {
00245 vec.x = x;
00246 vec.y = y;
00247 vec.z = z;
00248 }
00249
00250 void Math3d::SetVec(Vec3d &vec, const Vec3d &sourceVector)
00251 {
00252 vec.x = sourceVector.x;
00253 vec.y = sourceVector.y;
00254 vec.z = sourceVector.z;
00255 }
00256
00257 void Math3d::SetMat(Mat3d &matrix, float r1, float r2, float r3, float r4, float r5, float r6, float r7, float r8, float r9)
00258 {
00259 matrix.r1 = r1;
00260 matrix.r2 = r2;
00261 matrix.r3 = r3;
00262 matrix.r4 = r4;
00263 matrix.r5 = r5;
00264 matrix.r6 = r6;
00265 matrix.r7 = r7;
00266 matrix.r8 = r8;
00267 matrix.r9 = r9;
00268 }
00269
00270 void Math3d::SetMat(Mat3d &matrix, const Mat3d &sourceMatrix)
00271 {
00272 matrix.r1 = sourceMatrix.r1;
00273 matrix.r2 = sourceMatrix.r2;
00274 matrix.r3 = sourceMatrix.r3;
00275 matrix.r4 = sourceMatrix.r4;
00276 matrix.r5 = sourceMatrix.r5;
00277 matrix.r6 = sourceMatrix.r6;
00278 matrix.r7 = sourceMatrix.r7;
00279 matrix.r8 = sourceMatrix.r8;
00280 matrix.r9 = sourceMatrix.r9;
00281 }
00282
00283 void Math3d::SetRotationMat(Mat3d &matrix, const Vec3d &rotation)
00284 {
00285 const float alpha = rotation.x;
00286 const float beta = rotation.y;
00287 const float gamma = rotation.z;
00288
00289 const float sinfalpha = sinf(alpha);
00290 const float cosfalpha = cosf(alpha);
00291 const float sinfbeta = sinf(beta);
00292 const float cosfbeta = cosf(beta);
00293 const float sinfgamma = sinf(gamma);
00294 const float cosfgamma = cosf(gamma);
00295
00296 matrix.r1 = cosfbeta * cosfgamma;
00297 matrix.r2 = - cosfbeta * sinfgamma;
00298 matrix.r3 = sinfbeta;
00299 matrix.r4 = cosfalpha * sinfgamma + sinfalpha * sinfbeta * cosfgamma;
00300 matrix.r5 = cosfalpha * cosfgamma - sinfalpha * sinfbeta * sinfgamma;
00301 matrix.r6 = - sinfalpha * cosfbeta;
00302 matrix.r7 = sinfalpha * sinfgamma - cosfalpha * sinfbeta * cosfgamma;
00303 matrix.r8 = sinfalpha * cosfgamma + cosfalpha * sinfbeta * sinfgamma;
00304 matrix.r9 = cosfalpha * cosfbeta;
00305 }
00306
00307 void Math3d::SetRotationMat(Mat3d &matrix, float alpha, float beta, float gamma)
00308 {
00309 const float sinfalpha = sinf(alpha);
00310 const float cosfalpha = cosf(alpha);
00311 const float sinfbeta = sinf(beta);
00312 const float cosfbeta = cosf(beta);
00313 const float sinfgamma = sinf(gamma);
00314 const float cosfgamma = cosf(gamma);
00315
00316 matrix.r1 = cosfbeta * cosfgamma;
00317 matrix.r2 = - cosfbeta * sinfgamma;
00318 matrix.r3 = sinfbeta;
00319 matrix.r4 = cosfalpha * sinfgamma + sinfalpha * sinfbeta * cosfgamma;
00320 matrix.r5 = cosfalpha * cosfgamma - sinfalpha * sinfbeta * sinfgamma;
00321 matrix.r6 = - sinfalpha * cosfbeta;
00322 matrix.r7 = sinfalpha * sinfgamma - cosfalpha * sinfbeta * cosfgamma;
00323 matrix.r8 = sinfalpha * cosfgamma + cosfalpha * sinfbeta * sinfgamma;
00324 matrix.r9 = cosfalpha * cosfbeta;
00325 }
00326
00327 void Math3d::SetRotationMatYZX(Mat3d &matrix, const Vec3d &rotation)
00328 {
00329 Mat3d temp;
00330
00331 SetRotationMatY(matrix, rotation.y);
00332
00333 SetRotationMatZ(temp, rotation.z);
00334 MulMatMat(temp, matrix, matrix);
00335
00336 SetRotationMatX(temp, rotation.x);
00337 MulMatMat(temp, matrix, matrix);
00338 }
00339
00340 void Math3d::SetRotationMatX(Mat3d &matrix, float theta)
00341 {
00342 matrix.r1 = 1;
00343 matrix.r2 = matrix.r3 = matrix.r4 = matrix.r7 = 0;
00344 matrix.r5 = matrix.r9 = cosf(theta);
00345 matrix.r6 = matrix.r8 = sinf(theta);
00346 matrix.r6 = -matrix.r6;
00347 }
00348
00349 void Math3d::SetRotationMatY(Mat3d &matrix, float theta)
00350 {
00351 matrix.r5 = 1;
00352 matrix.r2 = matrix.r4 = matrix.r6 = matrix.r8 = 0;
00353 matrix.r1 = matrix.r9 = cosf(theta);
00354 matrix.r3 = matrix.r7 = sinf(theta);
00355 matrix.r7 = -matrix.r7;
00356 }
00357
00358 void Math3d::SetRotationMatZ(Mat3d &matrix, float theta)
00359 {
00360 matrix.r9 = 1;
00361 matrix.r3 = matrix.r6 = matrix.r7 = matrix.r8 = 0;
00362 matrix.r1 = matrix.r5 = cosf(theta);
00363 matrix.r2 = matrix.r4 = sinf(theta);
00364 matrix.r2 = -matrix.r2;
00365 }
00366
00367 void Math3d::SetRotationMat(Mat3d &matrix, const Vec3d &axis, float theta)
00368 {
00369 const float length = Length(axis);
00370 const float v1 = axis.x / length;
00371 const float v2 = axis.y / length;
00372 const float v3 = axis.z / length;
00373
00374 const float t1 = cosf(theta);
00375 const float t2 = 1 - t1;
00376 const float t3 = v1 * v1;
00377 const float t6 = t2 * v1;
00378 const float t7 = t6 * v2;
00379 const float t8 = sinf(theta);
00380 const float t9 = t8 * v3;
00381 const float t11 = t6 * v3;
00382 const float t12 = t8 * v2;
00383 const float t15 = v2 * v2;
00384 const float t19 = t2 * v2 * v3;
00385 const float t20 = t8 * v1;
00386 const float t24 = v3 * v3;
00387
00388 matrix.r1 = t1 + t2 * t3;
00389 matrix.r2 = t7 - t9;
00390 matrix.r3 = t11 + t12;
00391 matrix.r4 = t7 + t9;
00392 matrix.r5 = t1 + t2 * t15;
00393 matrix.r6 = t19 - t20;
00394 matrix.r7 = t11 - t12;
00395 matrix.r8 = t19 + t20;
00396 matrix.r9 = t1 + t2 * t24;
00397 }
00398
00399 void Math3d::SetRotationMatAxis(Mat3d &matrix, const Vec3d &axis, float theta)
00400 {
00401 const float length = Length(axis);
00402 const float x = axis.x / length;
00403 const float y = axis.y / length;
00404 const float z = axis.z / length;
00405
00406 const float s = sinf(theta);
00407 const float c = cosf(theta);
00408 const float t = 1.0f - c;
00409
00410 matrix.r1 = t * x * x + c;
00411 matrix.r2 = t * x * y - s * z;
00412 matrix.r3 = t * x * z + s * y;
00413 matrix.r4 = t * x * y + s * z;
00414 matrix.r5 = t * y * y + c;
00415 matrix.r6 = t * y * z - s * x;
00416 matrix.r7 = t * x * z - s * y;
00417 matrix.r8 = t * y * z + s * x;
00418 matrix.r9 = t * z * z + c;
00419 }
00420
00421
00422 void Math3d::MulMatVec(const Mat3d &matrix, const Vec3d &vec, Vec3d &result)
00423 {
00424 const float x = vec.x;
00425 const float y = vec.y;
00426 const float z = vec.z;
00427
00428 result.x = matrix.r1 * x + matrix.r2 * y + matrix.r3 * z;
00429 result.y = matrix.r4 * x + matrix.r5 * y + matrix.r6 * z;
00430 result.z = matrix.r7 * x + matrix.r8 * y + matrix.r9 * z;
00431 }
00432
00433 void Math3d::MulMatVec(const Mat3d &matrix, const Vec3d &vector1, const Vec3d &vector2, Vec3d &result)
00434 {
00435 const float x = vector1.x;
00436 const float y = vector1.y;
00437 const float z = vector1.z;
00438
00439 result.x = matrix.r1 * x + matrix.r2 * y + matrix.r3 * z + vector2.x;
00440 result.y = matrix.r4 * x + matrix.r5 * y + matrix.r6 * z + vector2.y;
00441 result.z = matrix.r7 * x + matrix.r8 * y + matrix.r9 * z + vector2.z;
00442 }
00443
00444 void Math3d::MulMatMat(const Mat3d &matrix1, const Mat3d &matrix2, Mat3d &result)
00445 {
00446 const float x1 = matrix1.r1 * matrix2.r1 + matrix1.r2 * matrix2.r4 + matrix1.r3 * matrix2.r7;
00447 const float x2 = matrix1.r1 * matrix2.r2 + matrix1.r2 * matrix2.r5 + matrix1.r3 * matrix2.r8;
00448 const float x3 = matrix1.r1 * matrix2.r3 + matrix1.r2 * matrix2.r6 + matrix1.r3 * matrix2.r9;
00449 const float x4 = matrix1.r4 * matrix2.r1 + matrix1.r5 * matrix2.r4 + matrix1.r6 * matrix2.r7;
00450 const float x5 = matrix1.r4 * matrix2.r2 + matrix1.r5 * matrix2.r5 + matrix1.r6 * matrix2.r8;
00451 const float x6 = matrix1.r4 * matrix2.r3 + matrix1.r5 * matrix2.r6 + matrix1.r6 * matrix2.r9;
00452 const float x7 = matrix1.r7 * matrix2.r1 + matrix1.r8 * matrix2.r4 + matrix1.r9 * matrix2.r7;
00453 const float x8 = matrix1.r7 * matrix2.r2 + matrix1.r8 * matrix2.r5 + matrix1.r9 * matrix2.r8;
00454 const float x9 = matrix1.r7 * matrix2.r3 + matrix1.r8 * matrix2.r6 + matrix1.r9 * matrix2.r9;
00455
00456 result.r1 = x1;
00457 result.r2 = x2;
00458 result.r3 = x3;
00459 result.r4 = x4;
00460 result.r5 = x5;
00461 result.r6 = x6;
00462 result.r7 = x7;
00463 result.r8 = x8;
00464 result.r9 = x9;
00465 }
00466
00467 void Math3d::MulVecTransposedVec(const Vec3d &vector1, const Vec3d &vector2, Mat3d &result)
00468 {
00469 result.r1 = vector1.x * vector2.x;
00470 result.r2 = vector1.x * vector2.y;
00471 result.r3 = vector1.x * vector2.z;
00472 result.r4 = vector1.y * vector2.x;
00473 result.r5 = vector1.y * vector2.y;
00474 result.r6 = vector1.y * vector2.z;
00475 result.r7 = vector1.z * vector2.x;
00476 result.r8 = vector1.z * vector2.y;
00477 result.r9 = vector1.z * vector2.z;
00478 }
00479
00480
00481 void Math3d::AddToVec(Vec3d &vec, const Vec3d &vectorToAdd)
00482 {
00483 vec.x += vectorToAdd.x;
00484 vec.y += vectorToAdd.y;
00485 vec.z += vectorToAdd.z;
00486 }
00487
00488 void Math3d::SubtractFromVec(Vec3d &vec, const Vec3d &vectorToSubtract)
00489 {
00490 vec.x -= vectorToSubtract.x;
00491 vec.y -= vectorToSubtract.y;
00492 vec.z -= vectorToSubtract.z;
00493 }
00494
00495 void Math3d::AddVecVec(const Vec3d &vector1, const Vec3d &vector2, Vec3d &result)
00496 {
00497 result.x = vector1.x + vector2.x;
00498 result.y = vector1.y + vector2.y;
00499 result.z = vector1.z + vector2.z;
00500 }
00501
00502 void Math3d::MulVecScalar(const Vec3d &vec, float scalar, Vec3d &result)
00503 {
00504 result.x = scalar * vec.x;
00505 result.y = scalar * vec.y;
00506 result.z = scalar * vec.z;
00507 }
00508
00509 void Math3d::MulMatScalar(const Mat3d &matrix, float scalar, Mat3d &result)
00510 {
00511 result.r1 = scalar * matrix.r1;
00512 result.r2 = scalar * matrix.r2;
00513 result.r3 = scalar * matrix.r3;
00514 result.r4 = scalar * matrix.r4;
00515 result.r5 = scalar * matrix.r5;
00516 result.r6 = scalar * matrix.r6;
00517 result.r7 = scalar * matrix.r7;
00518 result.r8 = scalar * matrix.r8;
00519 result.r9 = scalar * matrix.r9;
00520 }
00521
00522 void Math3d::SubtractVecVec(const Vec3d &vector1, const Vec3d &vector2, Vec3d &result)
00523 {
00524 result.x = vector1.x - vector2.x;
00525 result.y = vector1.y - vector2.y;
00526 result.z = vector1.z - vector2.z;
00527 }
00528
00529
00530 void Math3d::RotateVec(const Vec3d &vec, const Vec3d &rotation, Vec3d &result)
00531 {
00532 Mat3d matrix;
00533 SetRotationMat(matrix, rotation);
00534 MulMatVec(matrix, vec, result);
00535 }
00536
00537 void Math3d::TransformVec(const Vec3d &vec, const Vec3d &rotation, const Vec3d &translation, Vec3d &result)
00538 {
00539 Mat3d matrix;
00540 SetRotationMat(matrix, rotation);
00541 MulMatVec(matrix, vec, translation, result);
00542 }
00543
00544 void Math3d::RotateVecYZX(const Vec3d &vec, const Vec3d &rotation, Vec3d &result)
00545 {
00546 Mat3d matrix;
00547 SetRotationMatYZX(matrix, rotation);
00548 MulMatVec(matrix, vec, result);
00549 }
00550
00551 void Math3d::TransformVecYZX(const Vec3d &vec, const Vec3d &rotation, const Vec3d &translation, Vec3d &result)
00552 {
00553 Mat3d matrix;
00554 SetRotationMatYZX(matrix, rotation);
00555 MulMatVec(matrix, vec, translation, result);
00556 }
00557
00558
00559 float Math3d::ScalarProduct(const Vec3d &vector1, const Vec3d &vector2)
00560 {
00561 return vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z;
00562 }
00563
00564 void Math3d::CrossProduct(const Vec3d &vector1, const Vec3d &vector2, Vec3d &result)
00565 {
00566 const float x = vector1.y * vector2.z - vector1.z * vector2.y;
00567 const float y = vector1.z * vector2.x - vector1.x * vector2.z;
00568 result.z = vector1.x * vector2.y - vector1.y * vector2.x;
00569 result.x = x;
00570 result.y = y;
00571 }
00572
00573 void Math3d::NormalizeVec(Vec3d &vec)
00574 {
00575 const float length = sqrtf(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
00576
00577 if (length != 0.0f)
00578 {
00579 vec.x /= length;
00580 vec.y /= length;
00581 vec.z /= length;
00582 }
00583 }
00584
00585 float Math3d::Length(const Vec3d &vec)
00586 {
00587 return sqrtf(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
00588 }
00589
00590 float Math3d::SquaredLength(const Vec3d &vec)
00591 {
00592 return vec.x * vec.x + vec.y * vec.y + vec.z * vec.z;
00593 }
00594
00595 float Math3d::Distance(const Vec3d &vector1, const Vec3d &vector2)
00596 {
00597 const float x1 = vector1.x - vector2.x;
00598 const float x2 = vector1.y - vector2.y;
00599 const float x3 = vector1.z - vector2.z;
00600
00601 return sqrtf(x1 * x1 + x2 * x2 + x3 * x3);
00602 }
00603
00604 float Math3d::SquaredDistance(const Vec3d &vector1, const Vec3d &vector2)
00605 {
00606 const float x1 = vector1.x - vector2.x;
00607 const float x2 = vector1.y - vector2.y;
00608 const float x3 = vector1.z - vector2.z;
00609
00610 return x1 * x1 + x2 * x2 + x3 * x3;
00611 }
00612
00613 float Math3d::Angle(const Vec3d &vector1, const Vec3d &vector2)
00614 {
00615 const float sp = vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z;
00616 const float l1 = sqrtf(vector1.x * vector1.x + vector1.y * vector1.y + vector1.z * vector1.z);
00617 const float l2 = sqrtf(vector2.x * vector2.x + vector2.y * vector2.y + vector2.z * vector2.z);
00618
00619
00620 float r = sp / (l1 * l2);
00621 if (r > 1.0) r = 1.0;
00622 if (r < -1.0) r = -1.0;
00623 return acosf(r);
00624 }
00625
00626 float Math3d::EvaluateForm(const Vec3d &matrix1, const Mat3d &matrix2)
00627 {
00628 const float t0 = matrix1.x * matrix2.r1 + matrix1.y * matrix2.r4 + matrix1.z * matrix2.r7;
00629 const float t1 = matrix1.x * matrix2.r2 + matrix1.y * matrix2.r5 + matrix1.z * matrix2.r8;
00630 const float t2 = matrix1.x * matrix2.r3 + matrix1.y * matrix2.r6 + matrix1.z * matrix2.r9;
00631
00632 return t0 * matrix1.x + t1 * matrix1.y + t2 * matrix1.z;
00633 }
00634
00635 void Math3d::Transpose(const Mat3d &matrix, Mat3d &result)
00636 {
00637 float temp;
00638
00639 result.r1 = matrix.r1;
00640 result.r5 = matrix.r5;
00641 result.r9 = matrix.r9;
00642
00643 temp = matrix.r4;
00644 result.r4 = matrix.r2;
00645 result.r2 = temp;
00646
00647 temp = matrix.r3;
00648 result.r3 = matrix.r7;
00649 result.r7 = temp;
00650
00651 temp = matrix.r6;
00652 result.r6 = matrix.r8;
00653 result.r8 = temp;
00654
00655 }
00656
00657 void Math3d::Invert(const Mat3d &matrix, Mat3d &result)
00658 {
00659 const float a = matrix.r1;
00660 const float b = matrix.r2;
00661 const float c = matrix.r3;
00662 const float d = matrix.r4;
00663 const float e = matrix.r5;
00664 const float f = matrix.r6;
00665 const float g = matrix.r7;
00666 const float h = matrix.r8;
00667 const float i = matrix.r9;
00668
00669 float det_inverse = 1 / (-c * e * g + b * f * g + c * d * h - a * f * h - b * d * i + a * e * i);
00670
00671 result.r1 = (-f * h + e * i) * det_inverse;
00672 result.r2 = (c * h - b * i) * det_inverse;
00673 result.r3 = (-c * e + b * f) * det_inverse;
00674 result.r4 = (f * g - d * i) * det_inverse;
00675 result.r5 = (-c * g + a * i) * det_inverse;
00676 result.r6 = (c * d - a * f) * det_inverse;
00677 result.r7 = (-e * g + d * h) * det_inverse;
00678 result.r8 = (b * g - a * h) * det_inverse;
00679 result.r9 = (-b * d + a * e) * det_inverse;
00680 }
00681
00682 void Math3d::AddMatMat(const Mat3d &matrix1, const Mat3d &matrix2, Mat3d &matrix)
00683 {
00684 matrix.r1 = matrix1.r1 + matrix2.r1;
00685 matrix.r2 = matrix1.r2 + matrix2.r2;
00686 matrix.r3 = matrix1.r3 + matrix2.r3;
00687 matrix.r4 = matrix1.r4 + matrix2.r4;
00688 matrix.r5 = matrix1.r5 + matrix2.r5;
00689 matrix.r6 = matrix1.r6 + matrix2.r6;
00690 matrix.r7 = matrix1.r7 + matrix2.r7;
00691 matrix.r8 = matrix1.r8 + matrix2.r8;
00692 matrix.r9 = matrix1.r9 + matrix2.r9;
00693 }
00694
00695 void Math3d::AddToMat(Mat3d &matrix, const Mat3d &matrixToAdd)
00696 {
00697 matrix.r1 += matrixToAdd.r1;
00698 matrix.r2 += matrixToAdd.r2;
00699 matrix.r3 += matrixToAdd.r3;
00700 matrix.r4 += matrixToAdd.r4;
00701 matrix.r5 += matrixToAdd.r5;
00702 matrix.r6 += matrixToAdd.r6;
00703 matrix.r7 += matrixToAdd.r7;
00704 matrix.r8 += matrixToAdd.r8;
00705 matrix.r9 += matrixToAdd.r9;
00706 }
00707
00708 void Math3d::SubtractMatMat(const Mat3d &matrix1, const Mat3d &matrix2, Mat3d &result)
00709 {
00710 result.r1 = matrix1.r1 - matrix2.r1;
00711 result.r2 = matrix1.r2 - matrix2.r2;
00712 result.r3 = matrix1.r3 - matrix2.r3;
00713 result.r4 = matrix1.r4 - matrix2.r4;
00714 result.r5 = matrix1.r5 - matrix2.r5;
00715 result.r6 = matrix1.r6 - matrix2.r6;
00716 result.r7 = matrix1.r7 - matrix2.r7;
00717 result.r8 = matrix1.r8 - matrix2.r8;
00718 result.r9 = matrix1.r9 - matrix2.r9;
00719 }
00720
00721 float Math3d::Det(const Mat3d &matrix)
00722 {
00723 return matrix.r1 * matrix.r5 * matrix.r9
00724 + matrix.r2 * matrix.r6 * matrix.r7
00725 + matrix.r3 * matrix.r4 * matrix.r8
00726 - matrix.r3 * matrix.r5 * matrix.r7
00727 - matrix.r1 * matrix.r6 * matrix.r8
00728 - matrix.r2 * matrix.r4 * matrix.r9;
00729 }
00730
00731
00732 void Math3d::SetTransformation(Transformation3d &transformation, const Vec3d &rotation, const Vec3d &translation)
00733 {
00734 Math3d::SetRotationMat(transformation.rotation, rotation);
00735 Math3d::SetVec(transformation.translation, translation);
00736 }
00737
00738 void Math3d::SetTransformation(Transformation3d &transformation, const Transformation3d &sourceTransformation)
00739 {
00740 Math3d::SetMat(transformation.rotation, sourceTransformation.rotation);
00741 Math3d::SetVec(transformation.translation, sourceTransformation.translation);
00742 }
00743
00744 void Math3d::Invert(const Transformation3d &input, Transformation3d &result)
00745 {
00746 Math3d::Invert(input.rotation, result.rotation);
00747 Math3d::MulMatVec(result.rotation, input.translation, result.translation);
00748 Math3d::MulVecScalar(result.translation, -1, result.translation);
00749 }
00750
00751 void Math3d::MulTransTrans(const Transformation3d &transformation1, const Transformation3d &transformation2, Transformation3d &result)
00752 {
00753 Math3d::MulMatVec(transformation1.rotation, transformation2.translation, transformation1.translation, result.translation);
00754 Math3d::MulMatMat(transformation1.rotation, transformation2.rotation, result.rotation);
00755 }
00756
00757 void Math3d::MulTransVec(const Transformation3d &transformation, const Vec3d &vec, Vec3d &result)
00758 {
00759 Math3d::MulMatVec(transformation.rotation, vec, transformation.translation, result);
00760 }
00761
00762
00763 void Math3d::MulQuatQuat(const Quaternion &quat1, const Quaternion &quat2, Quaternion &result)
00764 {
00765 Vec3d v;
00766
00767 CrossProduct(quat1.v, quat2.v, v);
00768 v.x += quat1.w * quat2.v.x + quat1.w * quat2.v.x;
00769 v.y += quat1.w * quat2.v.y + quat1.w * quat2.v.y;
00770 v.z += quat1.w * quat2.v.z + quat1.w * quat2.v.z;
00771
00772 result.w = quat1.w * quat2.w - ScalarProduct(quat1.v, quat2.v);
00773 SetVec(result.v, v);
00774 }
00775
00776
00777 void Math3d::RotateVecQuaternion(const Vec3d &vec, const Vec3d &axis, float theta, Vec3d &result)
00778 {
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810 const float length = Length(axis);
00811 const float a = axis.x / length;
00812 const float b = axis.y / length;
00813 const float c = axis.z / length;
00814 const float d = theta;
00815
00816 const float v1 = vec.x;
00817 const float v2 = vec.y;
00818 const float v3 = vec.z;
00819
00820 const float t2 = a * b;
00821 const float t3 = a * c;
00822 const float t4 = a * d;
00823 const float t5 = -b * b;
00824 const float t6 = b * c;
00825 const float t7 = b * d;
00826 const float t8 = -c * c;
00827 const float t9 = c * d;
00828 const float t10 = -d * d;
00829
00830 result.x = 2 * ((t8 + t10) * v1 + (t6 - t4) * v2 + (t3 + t7) * v3 ) + v1;
00831 result.y = 2 * ((t4 + t6) * v1 + (t5 + t10) * v2 + (t9 - t2) * v3 ) + v2;
00832 result.z = 2 * ((t7 - t3) * v1 + (t2 + t9) * v2 + (t5 + t8) * v3 ) + v3;
00833 }
00834
00835 void Math3d::RotateVecAngleAxis(const Vec3d &vec, const Vec3d &axis, float theta, Vec3d &result)
00836 {
00837 Mat3d m;
00838 SetRotationMatAxis(m, axis, theta);
00839 MulMatVec(m, vec, result);
00840 }
00841
00842 float Math3d::Angle(const Vec3d &vector1, const Vec3d &vector2, const Vec3d &axis)
00843 {
00844 Vec3d u1, u2, n, temp;
00845 Mat3d testMatrix;
00846
00847 Math3d::SetVec(n, axis);
00848 Math3d::NormalizeVec(n);
00849
00850 Math3d::SetVec(u1, vector1);
00851 Math3d::MulVecScalar(n, Math3d::ScalarProduct(u1, n), temp);
00852 Math3d::SubtractFromVec(u1, temp);
00853 Math3d::NormalizeVec(u1);
00854
00855 Math3d::SetVec(u2, vector2);
00856 Math3d::MulVecScalar(n, Math3d::ScalarProduct(u2, n), temp);
00857 Math3d::SubtractFromVec(u2, temp);
00858 Math3d::NormalizeVec(u2);
00859
00860
00861 Math3d::SetRotationMatAxis(testMatrix, n, Math3d::Angle(u1, u2));
00862 Math3d::MulMatVec(testMatrix, u1, temp);
00863 const float d1 = Math3d::Distance(temp, u2);
00864
00865 Math3d::SetRotationMatAxis(testMatrix, n, -Math3d::Angle(u1, u2));
00866 Math3d::MulMatVec(testMatrix, u1, temp);
00867 const float d2 = Math3d::Distance(temp, u2);
00868
00869 return d1 < d2 ? Math3d::Angle(u1, u2) : -Math3d::Angle(u1, u2);
00870 }
00871
00872 void Math3d::GetAxisAndAngle(const Mat3d &R, Vec3d &axis, float &angle)
00873 {
00874 const float x = R.r8 - R.r6;
00875 const float y = R.r3 - R.r7;
00876 const float z = R.r4 - R.r2;
00877
00878 const float r = sqrtf(x * x + y * y + z * z);
00879 const float t = R.r1 + R.r5 + R.r9;
00880
00881 angle = atan2(r, t - 1);
00882
00883 Math3d::SetVec(axis, x, y, z);
00884 }
00885
00886 void Math3d::Average(const Vec3d &vector1, const Vec3d &vector2, Vec3d &result)
00887 {
00888 result.x = 0.5f * (vector1.x + vector2.x);
00889 result.y = 0.5f * (vector1.y + vector2.y);
00890 result.z = 0.5f * (vector1.z + vector2.z);
00891 }
00892
00893 void Math3d::Mean(const CVec3dArray &vectorList, Vec3d &result)
00894 {
00895 Mean(vectorList.GetElements(), vectorList.GetSize(), result);
00896 }
00897
00898 void Math3d::Mean(const Vec3d *pVectors, int nVectors, Vec3d &result)
00899 {
00900 if (nVectors == 0)
00901 {
00902 result = zero_vec;
00903 return;
00904 }
00905
00906 float sum_x = 0.0f, sum_y = 0.0f, sum_z = 0.0f;
00907
00908 for (int i = 0; i < nVectors; i++)
00909 {
00910 sum_x += pVectors[i].x;
00911 sum_y += pVectors[i].y;
00912 sum_z += pVectors[i].z;
00913 }
00914
00915 result.x = sum_x / float(nVectors);
00916 result.y = sum_y / float(nVectors);
00917 result.z = sum_z / float(nVectors);
00918 }