00001 // Vamos Automotive Simulator 00002 // Copyright (C) 2001--2002 Sam Varner 00003 // 00004 // This program is free software; you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation; either version 2 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 #include <vamos/geometry/Inertia_Tensor.h> 00019 00020 // Add a mass to the system at `position'. The inertia tensor 00021 // components are calculated here. 00022 void Vamos_Geometry::Inertia_Tensor:: 00023 add (double mass, const Three_Vector& position) 00024 { 00025 m_mass += mass; 00026 00027 // I_xx 00028 (*this) [0][0] += mass 00029 * (position [1] * position [1] + position [2] * position [2]); 00030 // I_xy 00031 (*this) [0][1] -= mass * (position [0] * position [1]); 00032 // I_xz 00033 (*this) [0][2] -= mass * (position [0] * position [2]); 00034 00035 // I_yy 00036 (*this) [1][1] += mass 00037 * (position [2] * position [2] + position [0] * position [0]); 00038 // I_yz 00039 (*this) [1][2] -= mass * (position [1] * position [2]); 00040 00041 // I_zz 00042 (*this) [2][2] += mass 00043 * (position [0] * position [0] + position [1] * position [1]); 00044 } 00045 00046 // Zero the components of the inertia tensor and also the mass. 00047 void Vamos_Geometry::Inertia_Tensor:: 00048 zero () 00049 { 00050 Three_Matrix::zero (); 00051 m_mass = 0.0; 00052 } 00053 00054 // Calculate the inverse of the inertia tensor. If the tensor is 00055 // singular, Bad_Inertia_Tensor is thrown. update() must be called 00056 // after all add()s have been performed. 00057 void Vamos_Geometry::Inertia_Tensor:: 00058 update () 00059 { 00060 // Fill in the symmetric components of the inertia tensor. 00061 (*this) [1][0] = (*this) [0][1]; 00062 (*this) [2][0] = (*this) [0][2]; 00063 (*this) [2][1] = (*this) [1][2]; 00064 00065 try 00066 { 00067 m_inverse = invert (); 00068 } 00069 catch (Vamos_Geometry::Singular_Matrix) 00070 { 00071 // If the inertia tensor is singular, throw an exception that tells 00072 // that the body is ill-formed. 00073 throw Bad_Inertia_Tensor (); 00074 } 00075 } 00076 00077 // Return the moment of inertia for a force applied at `position' in 00078 // the direction `force_direction'. `force_direction' need not be a 00079 // unit vector. 00080 double Vamos_Geometry::Inertia_Tensor:: 00081 inertia (const Three_Vector& position, const Three_Vector& force_direction) 00082 const 00083 { 00084 // The axis of rotation for a force applied in the direction of normal. 00085 // The maxnitude of axis is the rotational inertia about that axis. 00086 Three_Vector axis = m_inverse * (position.cross (force_direction.unit ())); 00087 00088 return m_mass / 00089 (1.0 00090 + m_mass 00091 * (axis.cross (position).project (force_direction.unit ())).abs ()); 00092 } 00093 00094 // Return the moment of inertia for TORQUE applied to the center of 00095 // mass. TORQUE need not be a unit vector. 00096 double Vamos_Geometry::Inertia_Tensor:: 00097 inertia (const Three_Vector& torque) const 00098 { 00099 return (torque.unit() * (*this)).abs (); 00100 }
1.4.6