// File: ScaledBodySegmentMassProperties.h // Portions copyright (c) 2007 Stanford University and Paul Mitiguy // Contributors: Paul Mitiguy and Jeff Reinbolt //-------------------------------------------------------------------------- // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject // to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. //-------------------------------------------------------------------------- #ifndef _SCALEDBODYSEGMENTMASSPROPERTIES_H_ #define _SCALEDBODYSEGMENTMASSPROPERTIES_H_ //---------------------------------------------------- #include "SimTKcommon.h" #include "StandardBodySegmentMassProperties.h" using namespace SimTK; //-------------------------------------------------------------------------- // Source: ADJUSTMENTS TO ZATSIORSKY-SELUYANOV'S SEGMENT INERTIA PARAMETERS // Paolo de Leva, Kinesiology Department, Indiana University, Bloomington, IN, 47405, USA // Journal of Biomechanics, Vol. 29, No. 9. pp. 1223 - 1230, 1996. // Note: The order of the columns on pg. 228 was changed to the following convention: // X-direction is what de Leva calls "Sagittal" // Y-direction is what de Leva calls "Longitudinal" // Z-direction is what de Leva calls "Traverse" // Note: The Foot's longitudinal and sagittal radii of gyration are // also transposed from the one's reported in the paper. //-------------------------------------------------------------------------- // Human body segment names: Head, Trunk, UpperArm, ForeArm, Hand, Thigh, Shank, Foot // segmentLengthInMM is measured in milli-meters and is the longest dimension (called "longitudinal" by de Leva) // segmentMassInKG is the body segment mass in kilograms // massCenterLengthInMM is the body segment mass center distance from the origin bony marker // XRadiusOfGyrationInMM is the body segment radius of gyration about its CM (called "Sagittal" by de Leva) // YRadiusOfGyrationInMM is the body segment radius of gyration about its CM (called "Longitudinal" by de Leva) // ZRadiusOfGyrationInMM is the body segment radius of gyration about its CM (called "Transverse" by de Leva) //-------------------------------------------------------------------------- class ScaledBodySegmentMassProperties { public: //-------------------------------------------- // Constructor // Note: Specifying a non-zero value for subjectBodySegmentLengthInMM will ignore the subjectTotalHeightInMM. // Otherwise the subjectBodySegmentLengthInMM is estimated from the subjectTotalHeightInMM and the StandardBodySegmentMassProperties. // Where practical, use of subjectBodySegmentLengthInMM is recommended because the // subjectBodySegmentLengthInMM is a measurement of the actual subject lengths. // Make measurements using the proper anatomical endpoints as described by de Leva. //-------------------------------------------- ScaledBodySegmentMassProperties( const StandardBodySegmentMassProperties &s, Real subjectTotalMassInKG, Real subjectTotalHeightInMM, Real subjectSegmentLengthInMM ) { // Copy the body segment name from the standard body strcpy( mySegmentName, s.getSegmentName() ); // If the last argument of the constructor is 0 (or negative), estimate the segment length if( (mySegmentLengthInMM = subjectSegmentLengthInMM) <= 0 ) { Real standardBodySegmentLengthInMM = s.getSegmentLengthInMM(); Real standardBodyTotalHeightInMM = s.getStandardBodyTotalHeightInMM(); mySegmentLengthInMM = standardBodySegmentLengthInMM * subjectTotalHeightInMM / standardBodyTotalHeightInMM; } // Now that mySegmentLengthInMM has been set (or estimated), scale the body segment mass properties. ScaleBodySegmentMassProperties( s, subjectTotalMassInKG ); } // Get this body segment's name const char* getBodySegmentName( void ) const { return mySegmentName; } // Check if "name" is the same as this body segment's name (is not case-sensitive) bool isBodySegmentName( const char *segmentName ) const { return strcmpi( segmentName, mySegmentName ) == 0; } // Get this subject-specific body segment length Real getSegmentLengthInMM( void ) const { return mySegmentLengthInMM; } // Get this subject-specific body segment's mass Real getMassInKG( void ) const { return myMassInKG; } // Get this subject-specific body segment's mass center distance from the origin bony marker Real getMassCenterLengthInMM( void ) const { return myMassCenterLengthInMM; } // Get this subject-specific body segment's X radius of gyration (called "Sagittal" by de Leva) Real getXRadiusOfGyrationInMM( void ) const { return myXRadiusOfGyrationInMM; } // Get this subject-specific body segment's Y radius of gyration (called "Longitudinal" by de Leva) Real getYRadiusOfGyrationInMM( void ) const { return myYRadiusOfGyrationInMM; } // Get this subject-specific body segment's Z radius of gyration (called "Transverse" by de Leva) Real getZRadiusOfGyrationInMM( void ) const { return myZRadiusOfGyrationInMM; } private: char mySegmentName[64]; Real mySegmentLengthInMM; Real myMassInKG; Real myMassCenterLengthInMM; Real myXRadiusOfGyrationInMM; Real myYRadiusOfGyrationInMM; Real myZRadiusOfGyrationInMM; // Set this subject's body segment mass properties by scaling with standard body segment void ScaleBodySegmentMassProperties( const StandardBodySegmentMassProperties &s, Real subjectTotalMassInKG ) { // Calculate this subject's body segment mass myMassInKG = s.getMassRatio() * subjectTotalMassInKG; // Calculate the ratio of this subject-specific body segment length to the standard body's segment length Real lengthRatio = mySegmentLengthInMM / s.getSegmentLengthInMM(); // Get this subject-specific body segment's mass center distance from the origin bony marker myMassCenterLengthInMM = s.getMassCenterRatio() * mySegmentLengthInMM; // Get this subject-specific body segment's X radius of gyration (called "Sagittal" by de Leva) myXRadiusOfGyrationInMM = s.getXRadiusOfGyrationRatio() * mySegmentLengthInMM; // Get this subject-specific body segment's Y radius of gyration (called "Longitudinal" by de Leva) myYRadiusOfGyrationInMM = s.getYRadiusOfGyrationRatio() * mySegmentLengthInMM; // Get this subject-specific body segment's Z radius of gyration (called "Longitudinal" by de Leva) myZRadiusOfGyrationInMM = s.getZRadiusOfGyrationRatio() * mySegmentLengthInMM; } }; //----------------------------------------------- #endif /* __SCALEDBODYSEGMENTMASSPROPERTIES_H_ */ //-----------------------------------------------