如何计算由多个推进器推动的二维物体的运动?
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
对物体施加简单的力
对象具有位置 x
、y
、旋转 r
和增量 dx
、dy
和 dr
。
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
}
正在开发一款由相互连接的方块组成的游戏(想想俄罗斯方块的形状)。每个方块都可以随机有一个推进器将其推向一个方向:上、下、左、右。如何计算物体在 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
对物体施加简单的力
对象具有位置 x
、y
、旋转 r
和增量 dx
、dy
和 dr
。
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
}