Math3d.cpp
Go to the documentation of this file.
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) 2014 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 }
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 }


asr_ivt
Author(s): Allgeyer Tobias, Hutmacher Robin, Kleinert Daniel, Meißner Pascal, Scholz Jonas, Stöckle Patrick
autogenerated on Thu Jun 6 2019 21:46:57