Маленькая помощь в реализации закона Хукса / упругой веревки? - PullRequest
0 голосов
/ 10 августа 2011

Пожалуйста, обратитесь к видео на

http://www.youtube.com/watch?v=_DyzwZJaDfM

"Коричневый" корпус управляется с помощью мыши, и когда мышь нажата, я вычисляю силу, используя закон Крюка (см. http://www.box2d.org/forum/viewtopic.php?f=4&t=116) и «голубое» тело должно притягиваться к «коричневому» телу.

Но, как видно из видео, «голубое» тело продолжает вращаться вокруг и не останавливается. Что я хотелорудие это "упругая веревка", как вещь.Сначала я попытался использовать DistanceJoint, но я не могу дать статическое расстояние до соединения.

вот моя реализация закона зацепок -

-(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() 

}

Любые советы, пожалуйста?

PS - гравитация мира составляет 0,0

1 Ответ

1 голос
/ 12 августа 2011

Закон Гука при включении в Второй закон Ньютона - это дифференциальное уравнение второго порядка: m d^2 x/dt^2 = - k x, где x - вектор. Как указывает Бета в комментариях, вы можете просто добавить трение. В отсутствие термина трения, такие орбиты, которые вы наблюдаете, являются обычными и будут продолжаться бесконечно. Обычный способ добавить трение состоит в том, чтобы добавить член, который пропорционален скорости, и, подобно члену Гука (-k*x), он также отрицателен, то есть противодействует движению.

Если я правильно читаю ваш код, у вас уже есть что-то вроде этого термина в комментариях после настройки forceMag. Но я не понимаю, как вы вычислили vrel, похоже, что это скалярное произведение между относительной скоростью и вектором, соединяющим два тела. vdiff уже правильная форма для этого. Также, в отличие от силы пружины, эта сила направлена ​​вдоль относительной скорости (vdiff). Таким образом, для его реализации я бы изменил строку, где вы вызываете ApplyForce на bodyA на

bodyA->ApplyForce(-1*diff - friction*vdiff,bodyB->GetPosition());
...