//----------------------------------------------------------------------------- // File: HelloCenterOfMass.cpp // Class: None // Parent: None // Children: None // Purpose: Takes several point masses and calculates center of mass and moment of inertia //----------------------------------------------------------------------------- // The following are standard C/C++ header files. // If a filename is enclosed inside < > it means the header file is in the Include directory. // If a filename is enclosed inside " " it means the header file is in the current directory. #include // Character Types #include // Mathematical Constants #include // Variable Argument Lists #include // Standard Input/Output Functions #include // Utility Functions #include // String Operations #include // Signals (Contol-C + Unix System Calls) #include // Nonlocal Goto (For Control-C) #include // Time and Date information #include // Verify Program Assertion #include // Error Codes (Used in Unix system()) #include // Floating Point Constants #include // Implementation Constants #include // Standard Definitions #include // Exception handling (e.g., try, catch throw) //----------------------------------------------------------------------------- #include "SimTKsimbody.h" using namespace SimTK; using namespace std; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Prototypes for local functions (functions not called by code in other files) //----------------------------------------------------------------------------- bool WriteStringToFile( const char outputString[], FILE *fptr ); bool WriteStringToScreen( const char outputString[] ) { return WriteStringToFile( outputString, stdout ); } bool WriteDoubleToFile( double x, int precision, FILE *fptr ); FILE* FileOpenWithMessageIfCannotOpen( const char *filename, const char *attribute ); bool WriteVec3ToFile( const Vec3 &v, int precision, FILE *fptr ); bool WriteMat33ToFile( const Mat33 &m, int precision, FILE *fptr ); //----------------------------------------------------------------------------- // The executable program starts here //----------------------------------------------------------------------------- int main( int numberOfCommandLineArguments, char *arrayOfCommandLineArguments[] ){ // Vectors to locations of each of the point masses const Vec3 Q1Loc( -1, 0, 0); const Vec3 Q2Loc( 0, 1, 0); const Vec3 Q3Loc( 1, 0, 0); const Vec3 Q4Loc( 0, -1, 0); // Sets each of the masses const Real mass1 = 1; const Real mass2 = 2; const Real mass3 = 2; const Real mass4 = 2; //Calculate the total mass const Real massSum = mass1 + mass2 + mass3 + mass4; //Calculate the center of mass const Vec3 centerOfMass = (mass1*Q1Loc + mass2*Q2Loc + mass3*Q3Loc + mass4*Q4Loc) / massSum; FILE *myFile = FileOpenWithMessageIfCannotOpen("HelloCenterOfMass.txt", "w"); //Write calculated center of mass to file WriteStringToFile("Center Of Mass = ", myFile); WriteVec3ToFile(centerOfMass, 7, myFile); Mat33 inertiaMatrix; const Mat33 identityMatrix(1, 0, 0, 0, 1, 0, 0, 0, 1); //calculate the inertia matrix about the origin inertiaMatrix = mass1*(identityMatrix*(dot(Q1Loc, Q1Loc))-Q1Loc*~Q1Loc) + mass2*(identityMatrix*(dot(Q2Loc, Q2Loc))-Q2Loc*~Q2Loc) + mass3*(identityMatrix*(dot(Q3Loc, Q3Loc))-Q3Loc*~Q3Loc) + mass4*(identityMatrix*(dot(Q4Loc, Q4Loc))-Q4Loc*~Q4Loc); WriteStringToFile("\n\n\nInertia about origin = ", myFile); WriteMat33ToFile(inertiaMatrix, 7, myFile); //Calculate the inertia matrix from COM inertiaMatrix = mass1*(identityMatrix*(dot((Q1Loc-centerOfMass), (Q1Loc-centerOfMass)))-(Q1Loc-centerOfMass)*~(Q1Loc-centerOfMass)) + mass2*(identityMatrix*(dot((Q2Loc-centerOfMass), (Q2Loc-centerOfMass)))-(Q2Loc-centerOfMass)*~(Q2Loc-centerOfMass)) + mass3*(identityMatrix*(dot((Q3Loc-centerOfMass), (Q3Loc-centerOfMass)))-(Q3Loc-centerOfMass)*~(Q3Loc-centerOfMass)) + mass4*(identityMatrix*(dot((Q4Loc-centerOfMass), (Q4Loc-centerOfMass)))-(Q4Loc-centerOfMass)*~(Q4Loc-centerOfMass)); WriteStringToFile("\n\n\nInertia about center of mass = ", myFile); WriteMat33ToFile(inertiaMatrix, 7, myFile); } //------------------------------------------------------------------------------- bool WriteStringToFile( const char outputString[], FILE *fptr ) { return fputs( outputString, fptr ) >=0; } //----------------------------------------------------------------------------- FILE* FileOpenWithMessageIfCannotOpen( const char *filename, const char *attribute ) { // Try to open the file FILE *Fptr1 = fopen( filename, attribute ); // If unable to open the file, issue a message if( !Fptr1 ) { WriteStringToScreen( "\n\n Unable to open the file: " ); WriteStringToScreen( filename ); WriteStringToScreen( "\n\n" ); } return Fptr1; } //----------------------------------------------------------------------------- bool WriteDoubleToFile( double x, int precision, FILE *fptr ) { // Ensure the precision (number of digits in the mantissa after the decimal point) makes sense. // Next, calculate the field width so it includes one extra space to the right of the number. if( precision < 0 || precision > 17 ) precision = 5; int fieldWidth = precision + 8; // Create the format specifier and print the number char format[20]; sprintf( format, " %%- %d.%dE", fieldWidth, precision ); return fprintf( fptr, format, x ) >= 0; } //----------------------------------------------------------------------------- bool WriteVec3ToFile( const Vec3 &v, int precision, FILE *fptr ){ bool output; output = WriteStringToFile( "\n[ ", fptr); if(!output) return output; output=WriteDoubleToFile( v[0], precision, fptr); if(!output) return output; output=WriteStringToFile( " , ", fptr); if(!output) return output; output=WriteDoubleToFile( v[1], precision, fptr); if(!output) return output; output=WriteStringToFile( " , ", fptr); if(!output) return output; output=WriteDoubleToFile( v[2], precision, fptr); if(!output) return output; output=WriteStringToFile( " ]", fptr); return output; } //----------------------------------------------------------------------------- bool WriteMat33ToFile( const Mat33 &m, int precision, FILE *fptr ) { bool output; Row3 row=m[0]; Vec3 rowTransp=~row; output = WriteVec3ToFile(rowTransp, precision, fptr); if(!output) return output; row=m[1]; rowTransp=~row; output = WriteVec3ToFile(rowTransp, precision, fptr); if(!output) return output; row=m[2]; rowTransp=~row; output = WriteVec3ToFile(rowTransp, precision, fptr); return output; }