//----------------------------------------------------------------------------- // File: Hello Vector.cpp // Class: None // Parent: None // Children: None // Purpose: Calculates Vector Operations for Two Sets of Vectors // Author: Daniel Jacobs //----------------------------------------------------------------------------- // 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 DoRequiredTasks( void ); bool GetStringFromFile( char inputString[], unsigned long maxSizeOfString, FILE *fptr ) { return fgets( inputString, maxSizeOfString, fptr ) != NULL; } bool GetStringFromKeyboard( char inputString[], unsigned long maxSizeOfString ) { return GetStringFromFile( inputString, maxSizeOfString, stdin ); } bool WriteStringToFile( const char outputString[], FILE *fptr ) { return fputs( outputString, fptr ) != EOF; } bool WriteStringToScreen( const char outputString[] ) { return WriteStringToFile( outputString, stdout ); } bool WriteIntegerToFile( int x, FILE *fptr ) { return fprintf( fptr, "%d", x) >= 0; } bool WriteDoubleToFile( double x, int precision, FILE *fptr ); bool WriteVec3ToFile( const Vec3 &v, int precision, FILE *fptr ); bool WriteMat33ToFile( const Mat33 &m, int precision, FILE *fptr ); FILE* FileOpenWithMessageIfCannotOpen( const char *filename, const char *attribute ); const char* ConvertStringToDouble( const char *s, double &returnValue, double defaultValue ); static double ConvertFromRadiansToDegrees ( double angleInRadians ); static double ConvertFromDegreesToRadians ( double angleInDegrees ); //----------------------------------------------------------------------------- // The executable program starts here //----------------------------------------------------------------------------- int main( int numberOfCommandLineArguments, char *arrayOfCommandLineArguments[] ) { // Simulate the multibody system bool simulationSucceeded = DoRequiredTasks(); // Keep the screen displayed until the user presses the Enter key WriteStringToScreen( "\n\n Press Enter to terminate the program: " ); getchar(); // The value returned by the main function is the exit status of the program. // A normal program exit returns 0 (other return values usually signal an error). return simulationSucceeded == true ? 0 : 1; } //----------------------------------------------------------------------------- bool DoRequiredTasks( void ) { // Define Vectors V and W Vec3 vectorV(2.0,3.0,4.0); Vec3 vectorW(5.0,-6.0,7.0); // Set up Answer Crib Real answerReal = 0.0; Vec3 answerVec; Mat33 answerMat; // Open a file to record the results (they are also displayed on screen) FILE *outputFile = FileOpenWithMessageIfCannotOpen( "HelloVectorResults.txt", "w" ); // Let the Math Begin! // Give everything the same precision int precision = 4; // 10v answerVec = 10*vectorV; WriteStringToFile( "1) 10v :", outputFile ); WriteVec3ToFile( answerVec, precision, outputFile ); WriteStringToFile( "\n", outputFile ); WriteStringToFile( "1) 10v :", stdout ); WriteVec3ToFile( answerVec, precision, stdout ); WriteStringToFile( "\n", stdout ); // v*10 answerVec = vectorV*10; WriteStringToFile( "2) v*10 :", outputFile ); WriteVec3ToFile( answerVec, precision, outputFile ); WriteStringToFile( "\n", outputFile ); WriteStringToFile( "2) v*10 :", stdout ); WriteVec3ToFile( answerVec, precision, stdout ); WriteStringToFile( "\n", stdout ); // v/10 answerVec = vectorV/10; WriteStringToFile( "3) v/10 :", outputFile ); WriteVec3ToFile( answerVec, precision, outputFile ); WriteStringToFile( "\n", outputFile ); WriteStringToFile( "3) v/10 :", stdout ); WriteVec3ToFile( answerVec, precision, stdout ); WriteStringToFile( "\n", stdout ); // v+w answerVec = vectorV + vectorW; WriteStringToFile( "4) v+w :", outputFile ); WriteVec3ToFile( answerVec, precision, outputFile ); WriteStringToFile( "\n", outputFile ); WriteStringToFile( "4) v+w :", stdout ); WriteVec3ToFile( answerVec, precision, stdout ); WriteStringToFile( "\n", stdout ); // v-w answerVec = vectorV - vectorW; WriteStringToFile( "5) v-w :", outputFile ); WriteVec3ToFile( answerVec, precision, outputFile ); WriteStringToFile( "\n", outputFile ); WriteStringToFile( "5) v-w :", stdout ); WriteVec3ToFile( answerVec, precision, stdout ); WriteStringToFile( "\n", stdout ); // v dot w answerReal = dot(vectorV,vectorW); WriteStringToFile( "6) dot(v,w) :", outputFile ); WriteDoubleToFile( answerReal, precision, outputFile ); WriteStringToFile( "\n", outputFile ); WriteStringToFile( "6) dot(v,w) :", stdout ); WriteDoubleToFile( answerReal, precision, stdout ); WriteStringToFile( "\n", stdout ); // v cross w answerVec = cross(vectorV,vectorW); WriteStringToFile( "7) cross(v,w) :", outputFile ); WriteVec3ToFile( answerVec, precision, outputFile ); WriteStringToFile( "\n", outputFile ); WriteStringToFile( "7) cross(v,w) :", stdout ); WriteVec3ToFile( answerVec, precision, stdout ); WriteStringToFile( "\n", stdout ); // w cross v answerVec = cross(vectorW,vectorV); WriteStringToFile( "8) cross(w,v) :", outputFile ); WriteVec3ToFile( answerVec, precision, outputFile ); WriteStringToFile( "\n", outputFile ); WriteStringToFile( "8) cross(w,v) :", stdout ); WriteVec3ToFile( answerVec, precision, stdout ); WriteStringToFile( "\n", stdout ); // v^n = norm(v)^n // v^2 = dot(v,v) answerReal = vectorV.norm()*vectorV.norm(); WriteStringToFile( "10) v^2 :", outputFile ); WriteDoubleToFile( answerReal, precision, outputFile ); WriteStringToFile( "\n", outputFile ); WriteStringToFile( "10) v^2 :", stdout ); WriteDoubleToFile( answerReal, precision, stdout ); WriteStringToFile( "\n", stdout ); // v^3 = dot(v,v)*norm(v) answerReal = dot(vectorV,vectorV)*vectorV.norm(); WriteStringToFile( "11) v^3 :", outputFile ); WriteDoubleToFile( answerReal, precision, outputFile ); WriteStringToFile( "\n", outputFile ); WriteStringToFile( "11) v^3 :", stdout ); WriteDoubleToFile( answerReal, precision, stdout ); WriteStringToFile( "\n", stdout ); // norm(v) answerReal = vectorV.norm(); WriteStringToFile( "11) norm(v) :", outputFile ); WriteDoubleToFile( answerReal, precision, outputFile ); WriteStringToFile( "\n", outputFile ); WriteStringToFile( "11) norm(v) :", stdout ); WriteDoubleToFile( answerReal, precision, stdout ); WriteStringToFile( "\n", stdout ); // norm(w) answerReal = vectorW.norm(); WriteStringToFile( "12) norm(w) :", outputFile ); WriteDoubleToFile( answerReal, precision, outputFile ); WriteStringToFile( "\n", outputFile ); WriteStringToFile( "12) norm(w) :", stdout ); WriteDoubleToFile( answerReal, precision, stdout ); WriteStringToFile( "\n", stdout ); //Unitvector(v) answerVec = vectorV.norm()*vectorV; WriteStringToFile( "13) unit(v) :", outputFile ); WriteVec3ToFile( answerVec, precision, outputFile ); WriteStringToFile( "\n", outputFile ); WriteStringToFile( "13) unit(v) :", stdout ); WriteVec3ToFile( answerVec, precision, stdout ); WriteStringToFile( "\n", stdout ); //angle(v,w) answerReal = acos(dot(vectorV,vectorW)/(vectorV.norm()*vectorW.norm())); WriteStringToFile( "14) angle(v,w) :", outputFile ); WriteDoubleToFile( answerReal, precision, outputFile ); WriteStringToFile( " (rad)", outputFile ); WriteDoubleToFile( ConvertFromRadiansToDegrees(answerReal), precision, outputFile ); WriteStringToFile( " (deg)", outputFile ); WriteStringToFile( "\n", outputFile ); WriteStringToFile( "14) angle(v,w) :", stdout ); WriteDoubleToFile( answerReal, precision, stdout ); WriteStringToFile( " (rad)", stdout ); WriteDoubleToFile( ConvertFromRadiansToDegrees(answerReal), precision, stdout ); WriteStringToFile( " (deg)", stdout ); WriteStringToFile( "\n", stdout ); //outer(v,w) answerMat = vectorV*vectorW.transpose(); WriteStringToFile( "15) outer(v,w) :\n", outputFile ); WriteMat33ToFile( answerMat, precision, outputFile ); WriteStringToFile( "\n", outputFile ); WriteStringToFile( "15) outer(v,w) :\n", stdout ); WriteMat33ToFile( answerMat, precision, stdout ); WriteStringToFile( "\n", stdout ); //outer(w,v) answerMat = vectorW*vectorV.transpose(); WriteStringToFile( "16) outer(w,v) :\n", outputFile ); WriteMat33ToFile( answerMat, precision, outputFile ); WriteStringToFile( "\n", outputFile ); WriteStringToFile( "16) outer(w,v) :\n", stdout ); WriteMat33ToFile( answerMat, precision, stdout ); WriteStringToFile( "\n", stdout ); return true; } //----------------------------------------------------------------------------- const char* ConvertStringToDouble( const char *s, double &returnValue, double defaultValue ) { // Default return value (in case the string is not a valid number) returnValue = defaultValue; // Check if s is a NULL string or "abc" or "123huh" or "(&junk#" or if( s != NULL ) { // Use the standard math function strtod to parse the number char *pointerToCharacterAfterNumber = NULL; double x = strtod( s, &pointerToCharacterAfterNumber ); // Ensure the number was not too large (overflow), such as 1.0E+999 or -1.0E-999 if( errno==ERANGE && x!=0.0 ) return NULL; // Ensure the character after the number is a space or '\0', not 'a' or 'z' or ... char characterAfterNumber = pointerToCharacterAfterNumber ? *pointerToCharacterAfterNumber : 'z'; if( characterAfterNumber == '\0' || isspace( characterAfterNumber ) ) { returnValue = x; return pointerToCharacterAfterNumber; } } return NULL; } //----------------------------------------------------------------------------- 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 ) { for( unsigned int i=0; i<3; i++ ) { double vi = v(i); if( !WriteDoubleToFile( vi, precision, fptr ) ) return false; } return true; } //----------------------------------------------------------------------------- bool WriteMat33ToFile( const Mat33 &m, int precision, FILE *fptr ) { for( unsigned int i=0; i<3; i++ ) { // Row3 &vi = m[i]; // m[i] returns the row and m(i) returns the column // if( !WriteVec3ToFile( vi, precision, fptr ) ) return false; for( unsigned int j=0; j<3; j++ ) { const Real mij = m[i][j]; if( !WriteDoubleToFile( mij, precision, fptr ) ) return false; } if( i<=1 && !WriteStringToFile( "\n", fptr ) ) return false; } return true; } //----------------------------------------------------------------------------- static double ConvertFromRadiansToDegrees ( double angleInRadians ) { return angleInRadians * 180/3.1415926535897932384626433832795028841971; } //----------------------------------------------------------------------------- static double ConvertFromDegreesToRadians ( double angleInDegrees ) { return angleInDegrees * 3.1415926535897932384626433832795028841971/180; } //-----------------------------------------------------------------------------