2014-07-01 20 views
1

我有一個關於如何將Box2D主體移動到特定位置的問題,而不使用此舉例。計算正確的衝突或力量將Box2D主體移動到特定位置 - Box2D

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

我有一些代碼,適用於applyForce(here):

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)或衝動(ApplyLinearImpulse)在特定的時間將身體移動到目標位置(非常精確)。

或上述代碼的解決方案。我的意思是計算maxSpeed將身體在特定時間移動到目標位置。

在我的谷歌搜索中,我找到了iforce關於預計軌跡 (here)的有趣文章。也許這也可能是幫助?

預先感謝您

回答

2

我認爲你有這主要是正確的,但你不檢查,看看身體會超調目標在接下來的時間步長。下面是我的什麼作品:

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); 
0

沒有爲一次性的方式施加的力由下式給出移動的距離(前面的回答表明,你可以在未來幀附加力糾正計算錯誤):

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.