00001 /*************************************************************************** 00002 * Copyright (C) 2005 by David Saxton * 00003 * david@bluehaze.org * 00004 * * 00005 * This program is free software; you can redistribute it and/or modify * 00006 * it under the terms of the GNU General Public License as published by * 00007 * the Free Software Foundation; either version 2 of the License, or * 00008 * (at your option) any later version. * 00009 ***************************************************************************/ 00010 00011 #include "mechanicsdocument.h" 00012 #include "mechanicsitem.h" 00013 #include "mechanicssimulation.h" 00014 00015 #include <cmath> 00016 #include <qtimer.h> 00017 00018 MechanicsSimulation::MechanicsSimulation( MechanicsDocument *mechanicsDocument ) 00019 : QObject(mechanicsDocument) 00020 { 00021 p_mechanicsDocument = mechanicsDocument; 00022 m_advanceTmr = new QTimer(this); 00023 connect( m_advanceTmr, SIGNAL(timeout()), this, SLOT(slotAdvance()) ); 00024 m_advanceTmr->start(1); 00025 } 00026 00027 MechanicsSimulation::~MechanicsSimulation() 00028 { 00029 } 00030 00031 void MechanicsSimulation::slotAdvance() 00032 { 00033 if ( p_mechanicsDocument && p_mechanicsDocument->canvas() ) 00034 p_mechanicsDocument->canvas()->advance(); 00035 } 00036 00037 RigidBody::RigidBody( MechanicsDocument *mechanicsDocument ) 00038 { 00039 p_mechanicsDocument = mechanicsDocument; 00040 p_overallParent = 0; 00041 } 00042 00043 RigidBody::~RigidBody() 00044 { 00045 } 00046 00047 bool RigidBody::addMechanicsItem( MechanicsItem *item ) 00048 { 00049 if ( !item || m_mechanicsItemList.contains(item) ) 00050 return false; 00051 00052 m_mechanicsItemList.append(item); 00053 findOverallParent(); 00054 return true; 00055 } 00056 00057 00058 void RigidBody::moveBy( double dx, double dy ) 00059 { 00060 if (overallParent()) 00061 overallParent()->moveBy( dx, dy ); 00062 } 00063 00064 00065 void RigidBody::rotateBy( double dtheta ) 00066 { 00067 if (overallParent()) 00068 overallParent()->rotateBy(dtheta); 00069 } 00070 00071 00072 bool RigidBody::findOverallParent() 00073 { 00074 p_overallParent = 0; 00075 if( m_mechanicsItemList.isEmpty()) return false; 00076 00077 m_mechanicsItemList.remove(0); 00078 00079 const MechanicsItemList::iterator end = m_mechanicsItemList.end(); 00080 for ( MechanicsItemList::iterator it = m_mechanicsItemList.begin(); it != end; ++it ) { 00081 MechanicsItem *parentItem = *it; 00082 MechanicsItem *parentCandidate = dynamic_cast<MechanicsItem*>((*it)->parentItem()); 00083 00084 while (parentCandidate) { 00085 parentItem = parentCandidate; 00086 parentCandidate = dynamic_cast<MechanicsItem*>(parentItem->parentItem()); 00087 } 00088 00089 if ( !p_overallParent ) // Must be the first item to test 00090 p_overallParent = parentItem; 00091 00092 if ( p_overallParent != parentItem ) { 00093 p_overallParent = 0; 00094 return false; 00095 } 00096 } 00097 return true; 00098 } 00099 00100 void RigidBody::updateRigidBodyInfo() 00101 { 00102 if (!p_overallParent) 00103 return; 00104 00105 m_mass = p_overallParent->mechanicsInfoCombined()->mass; 00106 m_momentOfInertia = p_overallParent->mechanicsInfoCombined()->momentOfInertia; 00107 } 00108 00109 Vector2D::Vector2D() 00110 { 00111 x = 0.; 00112 y = 0.; 00113 } 00114 00115 double Vector2D::length() const 00116 { 00117 return std::sqrt(x*x + y*y); 00118 00119 // better but not supported by build environment. =( 00120 // return std::hypot(x,y); 00121 } 00122 00123 RigidBodyState::RigidBodyState() 00124 { 00125 angularMomentum = 0.; 00126 } 00127 00128 #include "mechanicssimulation.moc"
1.5.1