mechanicssimulation.cpp

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"

Generated on Tue May 8 17:05:31 2007 for KTechLab by  doxygen 1.5.1