File indexing completed on 2024-04-21 05:43:48

0001 /***************************************************************************
0002  *   Copyright (C) 2005 by David Saxton                                    *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #include "mechanicssimulation.h"
0012 #include "mechanicsdocument.h"
0013 #include "mechanicsitem.h"
0014 
0015 #include <QTimer>
0016 #include <cmath>
0017 
0018 MechanicsSimulation::MechanicsSimulation(MechanicsDocument *mechanicsDocument)
0019     : QObject(mechanicsDocument)
0020 {
0021     p_mechanicsDocument = mechanicsDocument;
0022     m_advanceTmr = new QTimer(this);
0023     connect(m_advanceTmr, SIGNAL(timeout()), this, SLOT(slotAdvance()));
0024     m_advanceTmr->start(20); // it is not implemented anyway, so don't hog the CPU
0025 }
0026 
0027 MechanicsSimulation::~MechanicsSimulation()
0028 {
0029 }
0030 
0031 void MechanicsSimulation::slotAdvance()
0032 {
0033     //  if ( p_mechanicsDocument && p_mechanicsDocument->canvas() )
0034     //      p_mechanicsDocument->canvas()->advance();
0035 }
0036 
0037 RigidBody::RigidBody(MechanicsDocument *mechanicsDocument)
0038 {
0039     p_mechanicsDocument = mechanicsDocument;
0040     p_overallParent = nullptr;
0041 }
0042 
0043 RigidBody::~RigidBody()
0044 {
0045 }
0046 
0047 bool RigidBody::addMechanicsItem(MechanicsItem *item)
0048 {
0049     if (!item || m_mechanicsItemList.contains(item))
0050         return false;
0051 
0052     m_mechanicsItemList.append(item);
0053     findOverallParent();
0054     return true;
0055 }
0056 
0057 void RigidBody::moveBy(double dx, double dy)
0058 {
0059     if (overallParent())
0060         overallParent()->moveBy(dx, dy);
0061 }
0062 
0063 void RigidBody::rotateBy(double dtheta)
0064 {
0065     if (overallParent())
0066         overallParent()->rotateBy(dtheta);
0067 }
0068 
0069 bool RigidBody::findOverallParent()
0070 {
0071     p_overallParent = nullptr;
0072     if (m_mechanicsItemList.isEmpty())
0073         return false;
0074 
0075     m_mechanicsItemList.removeAll(nullptr);
0076 
0077     const MechanicsItemList::iterator end = m_mechanicsItemList.end();
0078     for (MechanicsItemList::iterator it = m_mechanicsItemList.begin(); it != end; ++it) {
0079         MechanicsItem *parentItem = *it;
0080         MechanicsItem *parentCandidate = dynamic_cast<MechanicsItem *>((*it)->parentItem());
0081 
0082         while (parentCandidate) {
0083             parentItem = parentCandidate;
0084             parentCandidate = dynamic_cast<MechanicsItem *>(parentItem->parentItem());
0085         }
0086 
0087         if (!p_overallParent)
0088             // Must be the first item to test
0089             p_overallParent = parentItem;
0090 
0091         if (p_overallParent != parentItem) {
0092             p_overallParent = nullptr;
0093             return false;
0094         }
0095     }
0096     return true;
0097 }
0098 
0099 void RigidBody::updateRigidBodyInfo()
0100 {
0101     if (!p_overallParent)
0102         return;
0103 
0104     m_mass = p_overallParent->mechanicsInfoCombined()->mass;
0105     m_momentOfInertia = p_overallParent->mechanicsInfoCombined()->momentOfInertia;
0106 }
0107 
0108 Vector2D::Vector2D()
0109 {
0110     x = 0.;
0111     y = 0.;
0112 }
0113 
0114 double Vector2D::length() const
0115 {
0116     return std::sqrt(x * x + y * y);
0117 }
0118 
0119 RigidBodyState::RigidBodyState()
0120 {
0121     angularMomentum = 0.;
0122 }
0123 
0124 #include "moc_mechanicssimulation.cpp"