step/stepcore
gravitation.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "gravitation.h"
00020 #include "particle.h"
00021 #include "rigidbody.h"
00022 #include <cmath>
00023
00024 namespace StepCore
00025 {
00026
00027 STEPCORE_META_OBJECT(GravitationForce, "Gravitation force", 0,
00028 STEPCORE_SUPER_CLASS(Item) STEPCORE_SUPER_CLASS(Force),
00029 STEPCORE_PROPERTY_RW(double, gravitationConst, STEPCORE_FROM_UTF8("N m²/kg²"),
00030 "Gravitation constant", gravitationConst, setGravitationConst))
00031
00032 STEPCORE_META_OBJECT(GravitationForceErrors, "Errors class for GravitationForce", 0,
00033 STEPCORE_SUPER_CLASS(ObjectErrors),
00034 STEPCORE_PROPERTY_RW(double, gravitationConstVariance, STEPCORE_FROM_UTF8("N m²/kg²"),
00035 "Gravitation constant variance", gravitationConstVariance, setGravitationConstVariance))
00036
00037 STEPCORE_META_OBJECT(WeightForce, "Weight force", 0,
00038 STEPCORE_SUPER_CLASS(Item) STEPCORE_SUPER_CLASS(Force),
00039 STEPCORE_PROPERTY_RW(double, weightConst, STEPCORE_FROM_UTF8("m/s²"), "Weight constant",
00040 weightConst, setWeightConst))
00041
00042 STEPCORE_META_OBJECT(WeightForceErrors, "Errors class for WeightForce", 0,
00043 STEPCORE_SUPER_CLASS(ObjectErrors),
00044 STEPCORE_PROPERTY_RW(double, weightConstVariance, STEPCORE_FROM_UTF8("m/s²"),
00045 "Weight constant variance", weightConstVariance, setWeightConstVariance))
00046
00047 GravitationForce* GravitationForceErrors::gravitationForce() const
00048 {
00049 return static_cast<GravitationForce*>(owner());
00050 }
00051
00052 WeightForce* WeightForceErrors::weightForce() const
00053 {
00054 return static_cast<WeightForce*>(owner());
00055 }
00056
00057 GravitationForce::GravitationForce(double gravitationConst)
00058 : _gravitationConst(gravitationConst)
00059 {
00060 gravitationForceErrors()->setGravitationConstVariance(
00061 square(Constants::GravitationalError));
00062 }
00063
00064 void GravitationForce::calcForce(bool calcVariances)
00065 {
00066 const BodyList::const_iterator end = world()->bodies().end();
00067 for(BodyList::const_iterator b1 = world()->bodies().begin(); b1 != end; ++b1) {
00068 if(!(*b1)->metaObject()->inherits<Particle>()) continue;
00069 for(BodyList::const_iterator b2 = b1+1; b2 != end; ++b2) {
00070 if(!(*b2)->metaObject()->inherits<Particle>()) continue;
00071 Particle* p1 = static_cast<Particle*>(*b1);
00072 Particle* p2 = static_cast<Particle*>(*b2);
00073
00074 Vector2d r = p2->position() - p1->position();
00075 double rnorm2 = r.norm2();
00076 Vector2d force = _gravitationConst * p1->mass() * p2->mass() * r / (rnorm2*sqrt(rnorm2));
00077 p1->applyForce(force);
00078 force.invert();
00079 p2->applyForce(force);
00080
00081 if(calcVariances) {
00082
00083 ParticleErrors* pe1 = p1->particleErrors();
00084 ParticleErrors* pe2 = p2->particleErrors();
00085 Vector2d rV = pe2->positionVariance() + pe1->positionVariance();
00086 Vector2d forceV = force.cSquare().cMultiply(
00087 Vector2d(gravitationForceErrors()->_gravitationConstVariance / square(_gravitationConst) +
00088 pe1->massVariance() / square(p1->mass()) +
00089 pe2->massVariance() / square(p2->mass())) +
00090 Vector2d(rV[0] * square(1/r[0] - 3*r[0]/rnorm2) + rV[1] * square(3*r[1]/rnorm2),
00091 rV[1] * square(1/r[1] - 3*r[1]/rnorm2) + rV[0] * square(3*r[0]/rnorm2)));
00092 pe1->applyForceVariance(forceV);
00093 pe2->applyForceVariance(forceV);
00094 }
00095 }
00096 }
00097 }
00098
00099 WeightForce::WeightForce(double weightConst)
00100 : _weightConst(weightConst)
00101 {
00102 weightForceErrors()->setWeightConstVariance(
00103 square(Constants::WeightAccelError));
00104 }
00105
00106 void WeightForce::calcForce(bool calcVariances)
00107 {
00108 Vector2d g(0, -_weightConst);
00109
00110 const BodyList::const_iterator end = world()->bodies().end();
00111 for(BodyList::const_iterator b1 = world()->bodies().begin(); b1 != end; ++b1) {
00112 if((*b1)->metaObject()->inherits<Particle>()) {
00113 Particle* p1 = static_cast<Particle*>(*b1);
00114 p1->applyForce(g*p1->mass());
00115 if(calcVariances) {
00116 ParticleErrors* pe1 = p1->particleErrors();
00117 Vector2d forceV(0, square(_weightConst)*pe1->massVariance()+
00118 square(p1->mass())*weightForceErrors()->weightConstVariance());
00119 pe1->applyForceVariance(forceV);
00120 }
00121 } else if((*b1)->metaObject()->inherits<RigidBody>()) {
00122 RigidBody* rb1 = static_cast<RigidBody*>(*b1);
00123 rb1->applyForce(g*rb1->mass(), rb1->position());
00124 if(calcVariances) {
00125 RigidBodyErrors* rbe1 = rb1->rigidBodyErrors();
00126 Vector2d forceV(0, square(_weightConst)*rbe1->massVariance()+
00127 square(rb1->mass())*weightForceErrors()->weightConstVariance());
00128 rbe1->applyForceVariance(g*rb1->mass(), rb1->position(),
00129 forceV, rbe1->positionVariance());
00130 }
00131 }
00132 }
00133 }
00134
00135 }
00136