//----------------------------------------------------------------------------- // File: PolygonMassDistributionProperties.cpp // Class: None // Parent: None // Children: None // Purpose: //----------------------------------------------------------------------------- // 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 ); bool WriteDoubleToScreen( double x, int precision) { return WriteDoubleToFile(x, precision, stdout); } FILE* FileOpenWithMessageIfCannotOpen( const char *filename, const char *attribute ); void UpdateBoundingBoxDimension( const Vec3 &vertexPosition, const Vec3 &xUnitVector, const Vec3 &yUnitVector, const Vec3 &zUnitVector, Vec6 &boundingBox, bool firstCallToFunction); Real ConvertFromDegreesToRadians( Real angleInDegrees ){return angleInDegrees/57.2957795;/*1 radian is approximately 57.3 degrees*/} //----------------------------------------------------------------------------- // The executable program starts here //----------------------------------------------------------------------------- int main( int numberOfCommandLineArguments, char *arrayOfCommandLineArguments[] ){ //unit vectors for the ground const Vec3 nx( 1, 0, 0); const Vec3 ny( 0, 1, 0); const Vec3 nz( 0, 0, 1); // initial unit vectors w.r.t. nx, ny, nz Vec3 bx(1, 0, 0); Vec3 by(0, 1, 0); Vec3 bz(0, 0, 1); // positions of the corners of the polygon const Vec3 B0Pos( 0, -1, 0); const Vec3 B1Pos( 1, 0, 0); const Vec3 B2Pos( 0, 3, 0); const Vec3 B3Pos( -1, 4, 0); const Vec3 B4Pos( -2, 2, 0); Rotation RotMat; Real theta = 0.0; while( theta <= 90){ Rotation RotMat2 = RotMat.aboutZ(ConvertFromDegreesToRadians(theta)); bx = RotMat2 * nx; by = RotMat2 * ny; bz = RotMat2 * nz; //Initial values of the bounding box's parameters are set to zero //boundingBox (xMin, xMax, yMin, yMax, zMin, zMax) Vec6 boundingBox(0, 0, 0, 0, 0, 0); //update the bounding boz dimensions for the new angle UpdateBoundingBoxDimension( B0Pos, bx, by, bz, boundingBox, 1); UpdateBoundingBoxDimension( B1Pos, bx, by, bz, boundingBox, 0); UpdateBoundingBoxDimension( B2Pos, bx, by, bz, boundingBox, 0); UpdateBoundingBoxDimension( B3Pos, bx, by, bz, boundingBox, 0); UpdateBoundingBoxDimension( B4Pos, bx, by, bz, boundingBox, 0); //Calculate the width, height, and area Real boundingWidth = boundingBox[1]-boundingBox[0]; Real boundingHeight = boundingBox[3]-boundingBox[2]; Real boundingArea = boundingWidth * boundingHeight; FILE* myFile = FileOpenWithMessageIfCannotOpen("PolygonMassDistributionResults.txt", "w"); //write out these values to the screen WriteStringToScreen("\n\n theta= "); WriteDoubleToScreen(theta, 6); WriteStringToScreen("\n xMin = "); WriteDoubleToScreen(boundingBox[0], 6); WriteStringToScreen(" xMax = "); WriteDoubleToScreen(boundingBox[1], 6); WriteStringToScreen("\n yMin = "); WriteDoubleToScreen(boundingBox[2], 6); WriteStringToScreen(" yMax = "); WriteDoubleToScreen(boundingBox[3], 6); WriteStringToScreen("\n Bounding rectangle area: "); WriteDoubleToScreen(boundingArea, 6); //write out these values to the file WriteStringToFile("\n\n theta= ", myFile); WriteDoubleToFile(theta, 6, myFile); WriteStringToFile("\n xMin = ", myFile); WriteDoubleToFile(boundingBox[0], 6, myFile); WriteStringToFile(" xMax = ", myFile); WriteDoubleToFile(boundingBox[1], 6, myFile); WriteStringToFile("\n yMin = ", myFile); WriteDoubleToFile(boundingBox[2], 6, myFile); WriteStringToFile(" yMax = ", myFile); WriteDoubleToFile(boundingBox[3], 6, myFile); WriteStringToFile("\n Bounding rectangle area: ", myFile); WriteDoubleToFile(boundingArea, 6, myFile); theta = theta+1; } printf( "\n\n Press Enter to terminate the program: " ); getchar(); return 0; } //------------------------------------------------------------------------------- bool WriteStringToFile( const char outputString[], FILE *fptr ) { return fputs( outputString, fptr ) >=0; } void UpdateBoundingBoxDimension( const Vec3 &vertexPosition, const Vec3 &xUnitVector, const Vec3 &yUnitVector, const Vec3 &zUnitVector, Vec6 &boundingBox, bool firstCallToFunction) { Real Xvertex = dot(vertexPosition, xUnitVector); Real Yvertex = dot(vertexPosition, yUnitVector); Real Zvertex = dot(vertexPosition, zUnitVector); if(firstCallToFunction){ //if this is the first call to the function, set all the edges of the bounding box to //the current values of x, y, and z boundingBox[0] = Xvertex; boundingBox[1] = Xvertex; boundingBox[2] = Yvertex; boundingBox[3] = Yvertex; boundingBox[4] = Zvertex; boundingBox[5] = Zvertex; } else{ //if this is not the first call, check to see if the current values are greater/less than //the previously stored max/mins if(Xvertex < boundingBox[0]) boundingBox[0] = Xvertex; else boundingBox[1] = Xvertex; if(Yvertex < boundingBox[2]) boundingBox[2] = Yvertex; else boundingBox[3] = Yvertex; if(Zvertex < boundingBox[4]) boundingBox[4] = Zvertex; else if(Zvertex > boundingBox[5]) boundingBox[5] = Zvertex; } } //----------------------------------------------------------------------------- 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; }