计算正确的脉冲或力以将Box2D体移动到特定位置 – Box2D

我有一个问题关于将Box2D机身移动到特定位置而不使用它。

body->SetTransform(targetVector,body->GetAngle()) 

我有一些适用于applyForce的代码( 这里 ):

 const float destinationControl = 0.3f; b2Vec2 missilePosition = _physicalBody->GetPosition(); b2Vec2 diff = targetPosition - missilePosition; float dist = diff.Length(); if (dist > 0) { // compute the aiming direction b2Vec2 direction = b2Vec2(diff.x / dist, diff.y / dist); // get the current missile velocity because we will apply a force to compensate this. b2Vec2 currentVelocity = _physicalBody->GetLinearVelocity(); // the missile ideal velocity is the direction to the target multiplied by the max speed b2Vec2 desireVelocity = b2Vec2(direction.x * maxSpeed, direction.y * maxSpeed); // compensate the current missile velocity by the desired velocity, based on the control factor b2Vec2 finalVelocity = control * (desireVelocity - currentVelocity); // transform our velocity into an impulse (get rid of the time and mass factor) float temp = (_physicalBody->GetMass() / normalDelta); b2Vec2 finalForce = b2Vec2(finalVelocity.x * temp, finalVelocity.y * temp); _physicalBody->ApplyForce(finalForce, _physicalBody->GetWorldCenter()); } 

但是当maxSpeed达到高位时,身体会快速移动到该点。

所以有人知道如何计算力( ApplyForce )或一个ApplyLinearImpulseApplyLinearImpulse )以在特定时间内将身体移动到目标位置(非常精确)。

或者是上面代码的解决方案。 我的意思是计算maxSpeed以在特定时间内将身体移动到目标位置。

在我的谷歌搜索中,我发现了iforce关于投影轨迹的有趣文章( 这里 )。 也许这也可能有所帮助?

先谢谢你

我认为你大多数都是正确的,但是你没有检查身体是否会在下一个时间步骤中超过目标。 这对我有用:

 b2Vec2 targetPosition = ...; float targetSpeed = ...; b2Vec2 direction = targetPosition - body->GetPosition(); float distanceToTravel = direction.Normalize(); // For most of the movement, the target speed is ok float speedToUse = targetSpeed; // Check if this speed will cause overshoot in the next time step. // If so, we need to scale the speed down to just enough to reach // the target point. (Assuming here a step length based on 60 fps) float distancePerTimestep = speedToUse / 60.0f; if ( distancePerTimestep > distanceToTravel ) speedToUse *= ( distanceToTravel / distancePerTimestep ); // The rest is pretty much what you had already: b2Vec2 desiredVelocity = speedToUse * direction; b2Vec2 changeInVelocity = desiredVelocity - body->GetLinearVelocity(); b2Vec2 force = body->GetMass() * 60.0f * changeInVelocity; body->ApplyForce( force, body->GetWorldCenter(), true ); 

单次施加力可以通过给定距离移动(先前的答案表明您可以通过未来帧中的附加力来校正计算中的误差):

 public static void applyForceToMoveBy(float byX, float byY, Body body) { force.set(byX, byY); force.sub(body.getLinearVelocity()); float mass = body.getMass(); force.scl(mass * 30.45f); body.applyForceToCenter(force, true); } 

已知限制:

 1) LinearVelocity effect was not tested; 2) calculation was tested with body linear damping = 0.5f. Appreciate, if somebody know how to add it into formula; 3) magic number 30.45f - maybe this could be fixed by point 2 or by world frame delta.