|
IVT
|
00001 // **************************************************************************** 00002 // This file is part of the Integrating Vision Toolkit (IVT). 00003 // 00004 // The IVT is maintained by the Karlsruhe Institute of Technology (KIT) 00005 // (www.kit.edu) in cooperation with the company Keyetech (www.keyetech.de). 00006 // 00007 // Copyright (C) 2013 Karlsruhe Institute of Technology (KIT). 00008 // All rights reserved. 00009 // 00010 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are met: 00012 // 00013 // 1. Redistributions of source code must retain the above copyright 00014 // notice, this list of conditions and the following disclaimer. 00015 // 00016 // 2. Redistributions in binary form must reproduce the above copyright 00017 // notice, this list of conditions and the following disclaimer in the 00018 // documentation and/or other materials provided with the distribution. 00019 // 00020 // 3. Neither the name of the KIT nor the names of its contributors may be 00021 // used to endorse or promote products derived from this software 00022 // without specific prior written permission. 00023 // 00024 // THIS SOFTWARE IS PROVIDED BY THE KIT AND CONTRIBUTORS “AS IS” AND ANY 00025 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00026 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00027 // DISCLAIMED. IN NO EVENT SHALL THE KIT OR CONTRIBUTORS BE LIABLE FOR ANY 00028 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00029 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00030 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00031 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00032 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00033 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 // **************************************************************************** 00035 // **************************************************************************** 00036 // Filename: Math3d.cpp 00037 // Author: Pedram Azad 00038 // Date: 2004 00039 // **************************************************************************** 00040 00041 00042 // **************************************************************************** 00043 // Includes 00044 // **************************************************************************** 00045 00046 #include <new> // for explicitly using correct new/delete operators on VC DSPs 00047 00048 #include "Math3d.h" 00049 #include "Helpers/BasicFileIO.h" 00050 00051 #include <math.h> 00052 00053 00054 00055 // **************************************************************************** 00056 // Variables 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 // Functions 00066 // **************************************************************************** 00067 00068 bool Math3d::LoadFromFile(Vec3d &vector, const char *pFilePath) 00069 { 00070 // not using fscanf, since it is buggy on some platforms 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 // not using fscanf, since it is buggy on some platforms 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 // not using fscanf, since it is buggy on some platforms 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 // added this. In some cases angle was numerically unstable 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 /*const float st = sinf(theta * 0.5f); 00780 const float ct = cosf(theta * 0.5f); 00781 00782 Quaternion a, q, r; 00783 Vec3d u; 00784 00785 // u = normalized axis vector 00786 SetVec(u, axis); 00787 NormalizeVec(u); 00788 00789 // set a 00790 SetVec(a.v, vec); 00791 a.w = 0; 00792 00793 // set q 00794 q.v.x = st * u.x; 00795 q.v.y = st * u.y; 00796 q.v.z = st * u.z; 00797 q.w = ct; 00798 00799 // calculate q * a 00800 MulQuatQuat(q, a, r); 00801 00802 // calculate conjugate quaternion of q 00803 q.v.x = -q.v.x; 00804 q.v.y = -q.v.y; 00805 q.v.z = -q.v.z; 00806 00807 // calculate q * a * q^ 00808 MulQuatQuat(r, q, r);*/ 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 // test which one of the two solutions is the right one 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 }