# BulletPhysics ship rotation

First of all, I'm a beginner in game physics, and I think this is a relatively easy problem that I'm not grasping.

Short Version:

I have a box(representing a ship on water) going forward with a constant thrust and I need to be able to steer it with the arrow keys so that it rotates and moves along a curved path. My code is not working and I'm obviously not understanding how to achieve this using Bullet-Physics.

Long version:

I'm creating a top-down-view naval game and I'm having a hard time trying to figure out how to use Bullet-physics to steer entities. I'm trying to make it feel somehow realistic by using a physics library.

I'm using SFML to prototype and test Bullet-physics. I have a 2D box representing a ship and during the main loop I'm updating its position and heading this way:

    box_bt->getMotionState()->getWorldTransform(trans);
box_sprite.setPosition(trans.getOrigin().getX(), trans.getOrigin().getY());


relevant code:

  (...)

btTransform trans;

while (window.isOpen())
{
dynamicsWorld->stepSimulation(1 / 60.f, 10);

// Apply drag force
box_bt->applyCentralForce(getDrag(box->getLinearVelocity().y()));

box_bt->getMotionState()->getWorldTransform(trans);
box_sprite.setPosition(trans.getOrigin().getX(), trans.getOrigin().getY());

if (Force < 0)
Force = 0;

// Method to apply thrust force along the Y axis relative to the rigidbody
// from: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=2366
btVector3    relativeForce = btVector3(0, -Force, 0);
btMatrix3x3& boxRot = box_bt->getWorldTransform().getBasis();
btVector3    correctedForce = boxRot * relativeForce;
box_bt->applyCentralForce(correctedForce);

(...)

if (event.key.code == sf::Keyboard::Up)
{
Force += 1000;
}
if (event.key.code == sf::Keyboard::Down)
{
Force -= 1000;
}
if (event.key.code == sf::Keyboard::Right)
{
box_bt->applyTorque(btVector3(0, 0, 1000));
}
if (event.key.code == sf::Keyboard::Right)
{
box_bt->applyTorque(btVector3(0, 0, -1000));
}

//draw box
}


I'm using applyTorque but I'm not sure if that is the best method to steer a ship in this case.

For the water drag/resistance force I'm using the simplified formula:

Force = vel*(k1*vel + k2*vel^2) where k1 and k2 being tweakable "drag coefficients."

btScalar getDrag(btScalar velocity)
{
btScalar k1 = 0.06f;
btScalar k2 = 0.03f;
return velocity * ((k1 * velocity) + (k2 * (velocity*velocity))) * 100;
}


I tried to get the drag force on all three axes but when I use the following code the ship doesn't behave right:

 btVector3 getDragVec(const btVector3& velocity)
{
btVector3 Rt(0, 0, 0);

btScalar k1 = 0.06f;
btScalar k2 = 0.03f;

Rt.setX(velocity.getX() * ((k1 * velocity.getX()) + (k2 * (velocity.getX()*velocity.getX()))) * 100); // 100 for scaling
Rt.setY(velocity.getY() * ((k1 * velocity.getY()) + (k2 * (velocity.getY()*velocity.getY()))) * 100);
Rt.setZ(velocity.getZ() * ((k1 * velocity.getZ()) + (k2 * (velocity.getZ()*velocity.getZ()))) * 100);

return Rt;
}


Both thrust and drag work well when moving forward, but once I try to introduce the steering part it rotates the box but it doesn't follow a curved path, the angles keep "flipping" once it gets to a certain limit, and the x-axis speed increases too much compared to the rotation.

Thank you for any insight!

• You should not rotate the ship. Because that is not how a ship normally works. Apply torque to the stern(Back of the ship) and it should rotate naturally. – KaareZ Nov 18 '16 at 12:50
• Agree with above commentor, ships don't rotate. They have to take a long angled breadth to achieve a turn. – Krythic Dec 19 '16 at 19:12

Introducing a rate of change to the current heading