Kine7ika
Kine7ika

Reputation: 15

How to calculate motion of a 2D object propelled by multiple thrusters?

Working on a game with objects made of of connected squares (think of Tetris shapes). Each square can randomly have a thruster pushing it in one direction: up, down, left, right. How can I calculate the total X/Y veloxities and rotation of the object in 2D space?

Edit: added picture to show a few example objects

enter image description here

Upvotes: 0

Views: 338

Answers (2)

Blindman67
Blindman67

Reputation: 54069

Simple force applied to an object

Object has position x,y, rotation r and deltas dx, dy, and dr.

 object { x : 0, y : 0, r : 0, dx : 0, dy : 0, dr : 0, mass : 1000};

Force is at a location x,y and in a direction.

The force is split into acceleration and angular acceleration components by the amount the force is directed to the center of mass and along the tangent to the center of math. Then divided by the mass for the acceleration and mass * distance from center of mass for angular acceleration. These accelerations are then added to the deltas x,y and r. Those deltas are then used to update the object location and rotation.

object.x += object.dx;
object.y += object.dy;
object.r += object.dr;

As the maths does not work if the force is applied at the center of mass the function checks if close and calls a simpler method that does not include rotation.

Code is Javascript and more details in the comments.

// apply force in direction to object at the center of mass
function applyForceCenter(object, force, direction){ 
    force /= object.mass; 
    object.dx += Math.cos(direction) * force;
    object.dy += Math.sin(direction) * force;
}

// apply force to object at location in direction 
// location is absolute
function applyForce(object, location, force, direction){ 
    // get the relative position of the force to the center of mass (COM)
    var ox = object.x - location.x;
    var oy =  object.y - location.y;
    var radius = Math.sqrt(ox * ox + oy * oy); // get distance from COM
    if(radius <= 1e-6){  // if too close use simple calcs
        applyForceCenter(object,force,direction);
        return;
    }
    // get the angle from the applied force to the center
    var toCenter = Math.atan2(oy, ox); // Yes y is first
    // the difference between the direction of force and direction to center
    var pheta = toCenter - direction;
    // reduce force by mass
    // Get the component parts of the force
    var Fv = Math.cos(pheta) * force; // The amount of the force that
                                      // contributes to acceleration
                                      // along the line to the center
    var Fr = Math.sin(pheta) * force; // The amount of the force that
                                      // contributes to angular acceleration
                                      // along the tangent from the center
    // Reduce acceleration by mass 
    Fv /= object.mass;
    // get the x,y components of that force along the line from where
    // it is applied to the center of mass
    object.dx += Math.cos(toCenter) * Fv;
    object.dy += Math.sin(toCenter) * Fv;

    // reduce angular acceleration by distance and mass
    Fr /= (radius  * object.mass);                                        
    object.dr += Fr; // add the change of rtoation

}

Upvotes: 1

cmourglia
cmourglia

Reputation: 2524

Well, maybe I'm missing something, but this looks like simple physics. You have to remember 2 things here :

sum of forces = mass * acceleration (or a(t+1) = Ftotal / m) and
v(t+1) = v(t) + a(t+1) * dt

So in your case you could just use something like

f_total = vec2(0, 0)
// Eventually add some other external forces

for_each thruster do
    f_total += thruster.force_vector

new_velocity = old_velocity + (f_total / mass) * dt

Upvotes: 0

Related Questions