• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdeedu
  • Sitemap
  • Contact Us
 

step/stepcore

joint.cc

Go to the documentation of this file.
00001 /* This file is part of StepCore library.
00002    Copyright (C) 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com>
00003 
00004    StepCore library 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    StepCore library 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 StepCore; if not, write to the Free Software
00016    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00017 */
00018 
00019 #include "joint.h"
00020 #include "particle.h"
00021 #include "rigidbody.h"
00022 #include <cstring>
00023 
00024 namespace StepCore {
00025 
00026 STEPCORE_META_OBJECT(Anchor, "Anchor: fixes position of the body", 0,
00027     STEPCORE_SUPER_CLASS(Item) STEPCORE_SUPER_CLASS(Joint),
00028     STEPCORE_PROPERTY_RW(Object*, body, STEPCORE_UNITS_NULL, "Body", body, setBody)
00029     STEPCORE_PROPERTY_RW(StepCore::Vector2d, position, "m", "Position", position, setPosition)
00030     STEPCORE_PROPERTY_RW(double, angle, "rad", "Angle", angle, setAngle))
00031 
00032 STEPCORE_META_OBJECT(Pin, "Pin: fixes position of a given point on the body", 0,
00033     STEPCORE_SUPER_CLASS(Item) STEPCORE_SUPER_CLASS(Joint),
00034     STEPCORE_PROPERTY_RW(Object*, body, STEPCORE_UNITS_NULL, "Body", body, setBody)
00035     STEPCORE_PROPERTY_RW(StepCore::Vector2d, localPosition, "m", "Position on the on a body", localPosition, setLocalPosition)
00036     STEPCORE_PROPERTY_RW(StepCore::Vector2d, position, "m", "Position in the world", position, setPosition))
00037 
00038 STEPCORE_META_OBJECT(Stick, "Massless stick which can be connected to bodies", 0,
00039     STEPCORE_SUPER_CLASS(Item) STEPCORE_SUPER_CLASS(Joint),
00040     STEPCORE_PROPERTY_RW(double, restLength, "m", "Rest length of the stick", restLength, setRestLength)
00041     STEPCORE_PROPERTY_RW(Object*, body1, STEPCORE_UNITS_NULL, "Body1", body1, setBody1)
00042     STEPCORE_PROPERTY_RW(Object*, body2, STEPCORE_UNITS_NULL, "Body2", body2, setBody2)
00043     STEPCORE_PROPERTY_RW(StepCore::Vector2d, localPosition1, "m",
00044                     "Local position 1", localPosition1, setLocalPosition1)
00045     STEPCORE_PROPERTY_RW(StepCore::Vector2d, localPosition2, "m",
00046                     "Local position 2", localPosition2, setLocalPosition2)
00047     STEPCORE_PROPERTY_R_D(StepCore::Vector2d, position1, "m", "Position1", position1)
00048     STEPCORE_PROPERTY_R_D(StepCore::Vector2d, position2, "m", "Position2", position2)
00049     )
00050 
00051 STEPCORE_META_OBJECT(Rope, "Massless rope which can be connected to bodies", 0,
00052     STEPCORE_SUPER_CLASS(Stick),)
00053 
00054 Anchor::Anchor(Object* body, const Vector2d& position, double angle)
00055     : _position(position), _angle(angle)
00056 {
00057     setBody(body);
00058     setColor(0xffff0000);
00059 }
00060 
00061 void Anchor::setBody(Object* body)
00062 {
00063     if(body) {
00064         if(body->metaObject()->inherits<Particle>()) {
00065             _body = body;
00066             _p = static_cast<Particle*>(body);
00067             _r = NULL;
00068             return;
00069         } else if(body->metaObject()->inherits<RigidBody>()) {
00070             _body = body;
00071             _p = NULL;
00072             _r = static_cast<RigidBody*>(body);
00073             return;
00074         }
00075     }
00076     _body = NULL;
00077     _p = NULL;
00078     _r = NULL;
00079 }
00080 
00081 int Anchor::constraintsCount()
00082 {
00083     if(_p) return 2;
00084     else if(_r) return 3;
00085     else return 0;
00086 }
00087 
00088 void Anchor::getConstraintsInfo(ConstraintsInfo* info, int offset)
00089 {
00090     if(_p) {
00091         info->value[offset  ] = _p->position()[0] - _position[0];
00092         info->value[offset+1] = _p->position()[1] - _position[1];
00093 
00094         info->derivative[offset  ] = _p->velocity()[0];
00095         info->derivative[offset+1] = _p->velocity()[1];
00096 
00097         info->jacobian.row(offset).w(_p->variablesOffset()+Particle::PositionOffset, 1);
00098         info->jacobian.row(offset+1).w(_p->variablesOffset()+Particle::PositionOffset+1, 1);
00099 
00100     } else if(_r) {
00101         info->value[offset  ] = _r->position()[0] - _position[0];
00102         info->value[offset+1] = _r->position()[1] - _position[1];
00103         info->value[offset+2] = _r->angle() - _angle;
00104 
00105         info->derivative[offset  ] = _r->velocity()[0];
00106         info->derivative[offset+1] = _r->velocity()[1];
00107         info->derivative[offset+2] = _r->angularVelocity();
00108 
00109         info->jacobian.row(offset).w(_r->variablesOffset()+RigidBody::PositionOffset, 1);
00110         info->jacobian.row(offset+1).w(_r->variablesOffset()+RigidBody::PositionOffset+1, 1);
00111         info->jacobian.row(offset+2).w(_r->variablesOffset()+RigidBody::AngleOffset, 1);
00112     }
00113 }
00114 
00115 Pin::Pin(Object* body, const Vector2d& localPosition, const Vector2d& position)
00116     : _localPosition(localPosition), _position(position)
00117 {
00118     setBody(body);
00119     setColor(0xffff0000);
00120 }
00121 
00122 void Pin::setBody(Object* body)
00123 {
00124     if(body) {
00125         if(body->metaObject()->inherits<Particle>()) {
00126             _body = body;
00127             _p = static_cast<Particle*>(body);
00128             _r = NULL;
00129             return;
00130         } else if(body->metaObject()->inherits<RigidBody>()) {
00131             _body = body;
00132             _p = NULL;
00133             _r = static_cast<RigidBody*>(body);
00134             return;
00135         }
00136     }
00137     _body = NULL;
00138     _p = NULL;
00139     _r = NULL;
00140 }
00141 
00142 int Pin::constraintsCount()
00143 {
00144     if(_p) {
00145         if(_localPosition.norm2() != 0) return 1; // XXX: add some epsilon here
00146         else return 2;
00147     } else if(_r) return 2;
00148     else return 0;
00149 }
00150 
00151 void Pin::getConstraintsInfo(ConstraintsInfo* info, int offset)
00152 {
00153     if(_p) {
00154         Vector2d r = _p->position() - _position;
00155         double lnorm2 = _localPosition.norm2();
00156 
00157         if(lnorm2 != 0) { // XXX: add some epsilon here
00158             info->value[offset] = (r.norm2() - lnorm2)*0.5;
00159             info->derivative[offset] = _p->velocity().innerProduct(r); 
00160 
00161             info->jacobian.row(offset).w(_p->variablesOffset()+Particle::PositionOffset, r[0]);
00162             info->jacobian.row(offset).w(_p->variablesOffset()+Particle::PositionOffset+1, r[1]);
00163 
00164             info->jacobianDerivative.row(offset).w(
00165                                 _p->variablesOffset()+Particle::PositionOffset, _p->velocity()[0]);
00166             info->jacobianDerivative.row(offset).w(
00167                                 _p->variablesOffset()+Particle::PositionOffset+1, _p->velocity()[1]);
00168         } else {
00169             info->value[offset  ]  = r[0];
00170             info->value[offset+1]  = r[1];
00171             info->derivative[offset  ] = _p->velocity()[0];
00172             info->derivative[offset+1] = _p->velocity()[1];
00173 
00174             info->jacobian.row(offset).w(_p->variablesOffset()+Particle::PositionOffset, 1);
00175             info->jacobian.row(offset+1).w(_p->variablesOffset()+Particle::PositionOffset+1, 1);
00176         }
00177     } else if(_r) {
00178         Vector2d r1 = _r->vectorLocalToWorld(_localPosition);
00179         Vector2d p1 = _r->position() + r1;
00180         Vector2d v1 = _r->velocityWorld(p1);
00181         double   av = _r->angularVelocity();
00182 
00183         info->value[offset  ] = p1[0] - _position[0];
00184         info->value[offset+1] = p1[1] - _position[1];
00185         info->derivative[offset  ] = v1[0];
00186         info->derivative[offset+1] = v1[1];
00187 
00188         info->jacobian.row(offset  ).w(_r->variablesOffset()+RigidBody::PositionOffset, 1);
00189         info->jacobian.row(offset+1).w(_r->variablesOffset()+RigidBody::PositionOffset+1, 1);
00190         info->jacobian.row(offset  ).w(_r->variablesOffset()+RigidBody::AngleOffset, -r1[1]);
00191         info->jacobian.row(offset+1).w(_r->variablesOffset()+RigidBody::AngleOffset,  r1[0]);
00192         info->jacobianDerivative.row(offset  ).w(_r->variablesOffset()+RigidBody::AngleOffset, -av*r1[0]);
00193         info->jacobianDerivative.row(offset+1).w(_r->variablesOffset()+RigidBody::AngleOffset, -av*r1[1]);
00194     }
00195 
00196 }
00197 
00198 Stick::Stick(double restLength, Object* body1, Object* body2,
00199            const Vector2d& localPosition1, const Vector2d& localPosition2)
00200     : _restLength(restLength), _localPosition1(localPosition1), _localPosition2(localPosition2)
00201 {
00202     setColor(0xffff0000);
00203     setBody1(body1);
00204     setBody2(body2);
00205 }
00206 
00207 void Stick::setBody1(Object* body1)
00208 {
00209     if(body1) {
00210         if(body1->metaObject()->inherits<Particle>()) {
00211             _body1 = body1;
00212             _p1 = static_cast<Particle*>(body1);
00213             _r1 = NULL;
00214             return;
00215         } else if(body1->metaObject()->inherits<RigidBody>()) {
00216             _body1 = body1;
00217             _p1 = NULL;
00218             _r1 = static_cast<RigidBody*>(body1);
00219             return;
00220         }
00221     }
00222     _body1 = NULL;
00223     _p1 = NULL;
00224     _r1 = NULL;
00225 }
00226 
00227 void Stick::setBody2(Object* body2)
00228 {
00229     if(body2) {
00230         if(body2->metaObject()->inherits<Particle>()) {
00231             _body2 = body2;
00232             _p2 = static_cast<Particle*>(body2);
00233             _r2 = NULL;
00234             return;
00235         } else if(body2->metaObject()->inherits<RigidBody>()) {
00236             _body2 = body2;
00237             _p2 = NULL;
00238             _r2 = static_cast<RigidBody*>(body2);
00239             return;
00240         }
00241     }
00242     _body2 = NULL;
00243     _p2 = NULL;
00244     _r2 = NULL;
00245 }
00246 
00247 Vector2d Stick::position1() const
00248 {
00249     if(_p1) return _p1->position() + _localPosition1;
00250     else if(_r1) return _r1->pointLocalToWorld(_localPosition1);
00251     else return _localPosition1;
00252 }
00253 
00254 Vector2d Stick::position2() const
00255 {
00256     if(_p2) return _p2->position() + _localPosition2;
00257     else if(_r2) return _r2->pointLocalToWorld(_localPosition2);
00258     else return _localPosition2;
00259 }
00260 
00261 Vector2d Stick::velocity1() const
00262 {
00263     if(_p1) return _p1->velocity();
00264     else if(_r1) return _r1->velocityLocal(_localPosition1);
00265     else return Vector2d(0);
00266 }
00267 
00268 Vector2d Stick::velocity2() const
00269 {
00270     if(_p2) return _p2->velocity();
00271     else if(_r2) return _r2->velocityLocal(_localPosition2);
00272     else return Vector2d(0);
00273 }
00274 
00275 int Stick::constraintsCount()
00276 {
00277     if(!_body1 && !_body2) return 0;
00278 
00279     if(_restLength != 0) return 1; // XXX: add some epsilon here
00280     else return 2;
00281 }
00282 
00283 void Stick::getConstraintsInfo(ConstraintsInfo* info, int offset)
00284 {
00285     if(!_body1 && !_body2) return;
00286 
00287     Vector2d p = position2() - position1();
00288     Vector2d v = velocity2() - velocity1();
00289 
00290     //qDebug("_restLength=%f", _restLength);
00291     if(_restLength != 0) {
00292         info->value[offset] = (p.norm2() - _restLength*_restLength)*0.5;
00293         info->derivative[offset] = p.innerProduct(v); 
00294 
00295         if(p[0] == 0 && p[1] == 0) p[0] = 0.1; //XXX: add epsilon
00296 
00297         if(_p1) {
00298             info->jacobian.row(offset).w(_p1->variablesOffset() + Particle::PositionOffset,   -p[0]);
00299             info->jacobian.row(offset).w(_p1->variablesOffset() + Particle::PositionOffset+1, -p[1]);
00300 
00301             info->jacobianDerivative.row(offset).w(_p1->variablesOffset() + Particle::PositionOffset,   -v[0]);
00302             info->jacobianDerivative.row(offset).w(_p1->variablesOffset() + Particle::PositionOffset+1, -v[1]);
00303 
00304         } else if(_r1) {
00305             Vector2d r1 = _r1->vectorLocalToWorld(_localPosition1);
00306 
00307             info->jacobian.row(offset).w(_r1->variablesOffset() + RigidBody::PositionOffset,   -p[0]);
00308             info->jacobian.row(offset).w(_r1->variablesOffset() + RigidBody::PositionOffset+1, -p[1]);
00309             info->jacobian.row(offset).w(_r1->variablesOffset() + RigidBody::AngleOffset, +p[0]*r1[1] - p[1]*r1[0]);
00310 
00311             info->jacobianDerivative.row(offset).w(_r1->variablesOffset() + RigidBody::PositionOffset,   -v[0]);
00312             info->jacobianDerivative.row(offset).w(_r1->variablesOffset() + RigidBody::PositionOffset+1, -v[1]);
00313             info->jacobianDerivative.row(offset).w(_r1->variablesOffset() + RigidBody::AngleOffset,
00314                                 + v[0]*r1[1] - v[1]*r1[0] + _r1->angularVelocity()*p.innerProduct(r1));
00315         }
00316 
00317         if(_p2) {
00318             info->jacobian.row(offset).w(_p2->variablesOffset() + Particle::PositionOffset,   p[0]);
00319             info->jacobian.row(offset).w(_p2->variablesOffset() + Particle::PositionOffset+1, p[1]);
00320 
00321             info->jacobianDerivative.row(offset).w(_p2->variablesOffset() + Particle::PositionOffset,   v[0]);
00322             info->jacobianDerivative.row(offset).w(_p2->variablesOffset() + Particle::PositionOffset+1, v[1]);
00323 
00324         } else if(_r2) {
00325             Vector2d r2 = _r2->vectorLocalToWorld(_localPosition2);
00326 
00327             info->jacobian.row(offset).w(_r2->variablesOffset() + RigidBody::PositionOffset,   p[0]);
00328             info->jacobian.row(offset).w(_r2->variablesOffset() + RigidBody::PositionOffset+1, p[1]);
00329             info->jacobian.row(offset).w(_r2->variablesOffset() + RigidBody::AngleOffset, -p[0]*r2[1] + p[1]*r2[0]);
00330 
00331             info->jacobianDerivative.row(offset).w(_r2->variablesOffset() + RigidBody::PositionOffset,   v[0]);
00332             info->jacobianDerivative.row(offset).w(_r2->variablesOffset() + RigidBody::PositionOffset+1, v[1]);
00333             info->jacobianDerivative.row(offset).w(_r2->variablesOffset() + RigidBody::AngleOffset,
00334                                 - v[0]*r2[1] + v[1]*r2[0] - _r2->angularVelocity()*p.innerProduct(r2));
00335         }
00336 
00337     } else {
00338         info->value[offset  ] = p[0];
00339         info->value[offset+1] = p[1];
00340 
00341         info->derivative[offset  ] = v[0];
00342         info->derivative[offset+1] = v[1];
00343 
00344         if(_p1) {
00345             info->jacobian.row(offset  ).w(_p1->variablesOffset() + Particle::PositionOffset,   -1);
00346             info->jacobian.row(offset+1).w(_p1->variablesOffset() + Particle::PositionOffset+1, -1);
00347 
00348         } else if(_r1) {
00349             Vector2d r1 = _r1->vectorLocalToWorld(_localPosition1);
00350             double   av = _r1->angularVelocity();
00351 
00352             info->jacobian.row(offset  ).w(_r1->variablesOffset() + Particle::PositionOffset,   -1);
00353             info->jacobian.row(offset+1).w(_r1->variablesOffset() + Particle::PositionOffset+1, -1);
00354 
00355             info->jacobian.row(offset  ).w(_r1->variablesOffset()+RigidBody::AngleOffset, +r1[1]);
00356             info->jacobian.row(offset+1).w(_r1->variablesOffset()+RigidBody::AngleOffset, -r1[0]);
00357             info->jacobianDerivative.row(offset  ).w(_r1->variablesOffset()+RigidBody::AngleOffset, +av*r1[0]);
00358             info->jacobianDerivative.row(offset+1).w(_r1->variablesOffset()+RigidBody::AngleOffset, +av*r1[1]);
00359         }
00360 
00361         if(_p2) {
00362             info->jacobian.row(offset  ).w(_p2->variablesOffset() + Particle::PositionOffset,   1);
00363             info->jacobian.row(offset+1).w(_p2->variablesOffset() + Particle::PositionOffset+1, 1);
00364 
00365         } else if(_r2) {
00366             Vector2d r2 = _r2->vectorLocalToWorld(_localPosition2);
00367             double   av = _r2->angularVelocity();
00368 
00369             info->jacobian.row(offset  ).w(_r2->variablesOffset() + Particle::PositionOffset,   1);
00370             info->jacobian.row(offset+1).w(_r2->variablesOffset() + Particle::PositionOffset+1, 1);
00371 
00372             info->jacobian.row(offset  ).w(_r2->variablesOffset()+RigidBody::AngleOffset, -r2[1]);
00373             info->jacobian.row(offset+1).w(_r2->variablesOffset()+RigidBody::AngleOffset, +r2[0]);
00374             info->jacobianDerivative.row(offset  ).w(_r2->variablesOffset()+RigidBody::AngleOffset, -av*r2[0]);
00375             info->jacobianDerivative.row(offset+1).w(_r2->variablesOffset()+RigidBody::AngleOffset, -av*r2[1]);
00376         }
00377     }
00378 }
00379 
00380 void Rope::getConstraintsInfo(ConstraintsInfo* info, int offset)
00381 {
00382     if(!_body1 && !_body2) return;
00383 
00384     Vector2d p = position2() - position1();
00385     Vector2d v = velocity2() - velocity1();
00386 
00387     if(_restLength != 0) {
00388         if(p.norm() >= _restLength) { // rope is in tension
00389             Stick::getConstraintsInfo(info, offset);
00390             info->forceMax[offset] = 0;
00391         } else { // rope is free
00392             info->value[offset] = 0;
00393             info->derivative[offset] = 0;
00394         }
00395     } else {
00396         Stick::getConstraintsInfo(info, offset);
00397     }
00398 }
00399 
00400 } // namespace StepCore
00401 
00402 

step/stepcore

Skip menu "step/stepcore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdeedu

Skip menu "kdeedu"
  • kalzium
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  •   docs
  •   src
  • parley
  •   stepcore
Generated for kdeedu by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal