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
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
}