Little help with implementing Hookes law/elastic rope?
Please refer to the video at
http://www.youtube.com/watch?v=_DyzwZJaDfM
The "brown" body is controlled with mouse and when mouse is pressed I calculate force using Hookes law (refereed to http://www.box2d.org/forum/viewtopic.php?f=4&t=116 ) and the "blue" body should attract to the开发者_如何学C "brown" body.
But as seen in the video,"blue" body keep orbiting around and doesn't come stop.What I wanted to implement is "elastic rope" like thing. First I tried using DistanceJoint ,but I cannot give a static distance to the joint.
here is my implementation for hookes law -
-(void)applyHookesLaw:(b2Body*)bodyA:(b2Body*)bodyB:(float) k:(float) friction:(float)desiredDist
{
b2Vec2 pA=bodyA->GetPosition();
b2Vec2 pB=bodyB->GetPosition();
b2Vec2 diff=pB- pA;
b2Vec2 vA=bodyA->GetLinearVelocity();
b2Vec2 vB=bodyB->GetLinearVelocity();
b2Vec2 vdiff=vB-vA;
float dx=diff.Normalize();
float vrel=vdiff.x * diff.x + vdiff.y * diff.y;
float forceMag= -k*(dx-desiredDist);//-friction*vrel;
diff*=forceMag;
bodyA->ApplyForce(-1*diff,bodyB->GetPosition());
//bodyA->wakeUp()
}
Any tips please?
PS - gravity of the world is 0.0
Hooke's law when incorporated into Newton's Second law is a second order differential equation: m d^2 x/dt^2 = - k x
, where x is is a vector. As Beta points out in the comments, you can just add friction. Absent a friction term, orbits like you observe are common, and they will continue indefinitely. The usual way add friction is to add a term that is proportional to velocity, and like the Hookean term (-k*x
), it is also negative, i.e. it opposes the motion.
If I'm reading your code correctly, you already have something like that term in the comments following setting forceMag
. But, I don't understand your calculation of vrel
, it looks like the dot product between the relative velocity and the vector joining the two bodies. vdiff
is already the correct form for this. Also, unlike the spring force, this force is directed along the relative velocity (vdiff
). So, to implement it I'd change the line where you call ApplyForce
on bodyA
to
bodyA->ApplyForce(-1*diff - friction*vdiff,bodyB->GetPosition());
精彩评论