Tutorial: demo_coords.cpp
#include "physics/CHapidll.h" #include "physics/CHglobal.h" #include "core/CHtrasform.h" #include "core/CHmatrix.h" #include "core/CHlog.h" #include "core/CHvector.h" #include "core/CHexception.h" using namespace chrono; int main(int argc, char* argv[]) { // To write something to the console, use the chrono::GetLog() // statement, which returns a global output stream to the console (just // like the std::out stream). GetLog() << "CHRONO foundation classes demo: math\n\n"; // Initialize DLL (also returns the handle to the global structure // with global settings, maybe you need to use them later..) ChGlobals* GLOBAL_Vars = DLL_CreateGlobals();Now here some example about the basic features of the ChMatrix<> class (you can use the shorter alias 'Matrix' for less typing..).
// Create a default 3x3 matrix chrono::Matrix ma; // Create a 4x4 matrix chrono::Matrix mm(4,4); // Fill a matrix with an element mm.FillElem(0.1); // Print a matrix to cout (ex. the console, if open) mm.PrintMatrix(); // Create a 5x7 random matrix chrono::Matrix me(5,7); me.FillRandom(-1, 2); // Transpose the matrix in place me.MatrTranspose(); // Resets the matrix to zero (and modify size, if necessary). me.Reset(2,2); // Create a diagonal matrix chrono::Matrix md(4,4); md.FillDiag(3); // Use the () operator to reference single elements md(0,0) = 10; md(1,2) = md(0,0)+md(1,1); md.Element(2,2) = 4; // The md.Element(.,.) function has the same effect as md(.,.) // Copy constructor chrono::Matrix ma1(md); // The - unary operator returns a negated matrix chrono::Matrix ma2(-mm); // A late copy - matrix will be resized if necessary chrono::Matrix ma3(8,4); ma3.CopyFromMatrix(ma1); // Transposed copy. // This is faster than doing: ma3.CopyFromMatrix(ma2); ma3.MatrTranspose(); ma3.CopyFromMatrixT(ma1);
Note that you can use the + * - *= += -= operators to perform matrix
algebra with an easy and compact notation.
WARNING: + - * operators may introduce overhead because they
may instance temporary matrix objects
as intermediate results. Use *= -= += operators whenever possible,
or use the
specific Add() Multiply() functions, for max computational speed.
// Use the + * - *= += -= operators to perform matrix algebra. // WARNING: + - * operators may introduce overhead because they may instance temporary // matrix objects as intermediate results. Use *= -= += operators whenever possible, // or use the specific Add() Multiply() functions, for max computational speed. // Note: size of result is automatically set because of copy constructor chrono::Matrix result(ma1+ma2); // Using the assignment operator (size of result may be automatically reset) result = ma1+ma2; // Another way to do operations (more intricated, but allows higher performances) // Note that, doing this, you must prepare 'result' with already exact column/row size! result.MatrAdd(ma1,ma2); // You can also use the += operator (often this minimizes the need // of intermediate temp.matrices) result = ma1; result += ma2; // Different ways to do subtraction.. result = ma1-ma2; result.MatrSub(ma1,ma2); result = ma1; result -= ma2; // Multiplications between two matrices, different methods.. result = ma1*ma2; result.MatrMultiply(ma1,ma2); // Multiplication between matrix and scalars, different methods.. result = ma1*10; result = ma1; result.MatrScale(10); GetLog() << result; result = ma1; result *=10; GetLog() << result; // The dot multiplication chrono::Matrix mmv1(5,1); chrono::Matrix mmv2(5,1); mmv1.FillRandom(1,3); mmv2.FillRandom(2,4); double mdot = chrono::Matrix::MatrDot(&mmv1, &mmv2); // Matrix comparison chrono::Matrix mmv3(mmv2); if (mmv2==mmv3) GetLog() << "Matrices are exactly equal \n"; // Tolerance comparison mmv3.Element(2,0)+=0.001; if (mmv2.Equals(mmv3,0.002)) GetLog() << "Matrices are equal within tol 0.002 \n";Also, here are some examples about matrix/quaternion multiplication, also with the Matr34_x_Quat() and Matr44_x_Quat() special multiplication functions, which are optimized for speed:
chrono::Vector mvect(1,2,3); chrono::Quaternion mquat(1,2,3,4); chrono::Matrix mta1; mta1.FillRandom(-1, 2); // Vector transformation, typical product [A]*v chrono::Vector vres = mta1.Matr_x_Vect(mvect); // Also with more compact syntax: operator * between matrix and vector.. chrono::Vector vres2 = mta1*mvect; if (vres == vres2) GetLog() << "vectors are equal \n"; // .. same, but transposed matrix vres = mta1.MatrT_x_Vect(mvect); // Custom multiplication functions for 3x4 matrices and quaternions: mta1.Reset(3,4); mta1.FillRandom(-1, 2); vres = mta1.Matr34_x_Quat(mquat); chrono::Quaternion qres = mta1.Matr34T_x_Vect(mvect); mta1.Reset(4,4); mta1.FillRandom(-1, 2); qres = mta1.Matr44_x_Quat(mquat); // How to use the ChTrasform or ChCoordsys functions to transform points // from/to local coordinates in 3D: chrono::Vector mvect2; chrono::Vector mvect2b; chrono::Vector mvect1(2,3,4); // local point to transform chrono::Vector vtraslA(5,6,7); // translation of coordsystem chrono::Quaternion qrotA(1, 3, 4, 5); // rotation of coordsys.(as unit quaternion, must be normalized) qrotA.Normalize(); // given a quaternion, sets the corresponding [A] rotation matrix chrono::Matrix mrotA; mrotA.Set_A_quaternion(qrotA); // ..you may use also a coordsystem object, representing both // translation and rotation. chrono::Coordsys csysA (vtraslA, qrotA); // Now perform the transformation, like in v'=t+[A]*v // NOTE: all the following ways will give the same result, so you // can use them equivalently! // (the 1st method however is a bit faster..) mvect2 = chrono::ChTrasform<>::TrasformLocalToParent(mvect1, vtraslA, mrotA); mvect2 = chrono::ChTrasform<>::TrasformLocalToParent(mvect1, vtraslA, qrotA); mvect2 = csysA.TrasformLocalToParent(mvect1); mvect2 = vtraslA + mrotA*mvect1;Delete previously initialized global library data, print something and that's all:
DLL_DeleteGlobals(); GetLog() << "\n CHRONO execution terminated."; return 0; }