【问题标题】:Calculate correct impluse or force to move a Box2D body to a specific position - Box2D计算正确的内推力或力以将 Box2D 主体移动到特定位置 - Box2D
【发布时间】:2015-12-14 06:11:19
【问题描述】:

例如,我有一个关于将 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)。也许这也有帮助?

提前谢谢你

【问题讨论】:

    标签: ios iphone math box2d physics


    【解决方案1】:

    我认为你基本上是正确的,但你没有检查身体是否会在下一个时间步超过目标。这对我有用:

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

    【讨论】:

      【解决方案2】:

      有一种方法可以让单次施加的力移动给定的距离(之前的答案表明您可以在未来的帧中通过额外的力来纠正计算中的错误):

      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.
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多