如何计算由多个推进器推动的二维物体的运动?

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

正在开发一款由相互连接的方块组成的游戏(想想俄罗斯方块的形状)。每个方块都可以随机有一个推进器将其推向一个方向:上、下、左、右。如何计算物体在 2D space 中的总 X/Y 速度和旋转?

编辑:添加图片以显示一些示例对象

好吧,也许我漏掉了什么,但这看起来像是简单的物理学。你必须记住两件事:

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

所以在你的情况下你可以使用类似

的东西
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

对物体施加简单的力

对象具有位置 xy、旋转 r 和增量 dxdydr

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

力位于 location x,y 和 direction.

力被分成加速度和 angular 加速度分量,根据力指向质心的量和沿着数学中心的切线的量。然后除以加速度的质量和 angular 加速度的质量 * 距质心的距离。然后将这些加速度添加到增量 x、y 和 r 中。然后使用这些增量来更新对象位置和旋转。

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

由于在质心处施加力时数学不起作用,因此该函数会检查是否关闭并调用不包括旋转的更简单方法。

代码是 Javascript,评论中有更多详细信息。

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

}