书名:代码本色:用编程模拟自然系统
作者:Daniel Shiffman
译者:周晗彬
ISBN:978-7-115-36947-5
目录
5.12 回到力的话题
1、Box2D力的作用
- Box2D中也存在力的作用,因为我们看到前面的各种矩形和圆会在屏幕中旋转和移动。但到目前为止,我们只学会了如何操纵其中的一个全局作用力——重力。
box2d = new PBox2D(this);
box2d.createWorld();
box2d.setGravity(0, -20); 设置全局的重力
- 如果想在Box2D中使用第2章的技术,我们只需要研究其中的applyForce()函数
- Mover类实现了这个applyForce()函数:它的参数是一个向量,函数内部将这个向量除以质量,再把得到的结果加到运动者对象的加速度上。
- Box2D也有同样的函数,而且不需要我们去实现它。我们可以直接在Box2D的物体上调用applyForce()函数!
class Box {
Body body;
void applyForce(Vec2 force) {
Vec2 pos = body.getWorldCenter();
body.applyForce(force, pos); 调用物体的applyForce()函数
}
}
以上程序得到一个力向量,并将它作用在Box2D物体上。和第2章中的示例程序相比,Box2D是一个更复杂的物理引擎。前面的示例程序假设力总是作用在物体的中心点,但在Box2D中,我们需要指定力在物体上的作用位置。尽管以上程序还是将力作用在物体的中心点上,但力的作用点是可设置的,它可以不在中心点上。
假设我们需要模拟引力,在第2章,我们在Attractor类中模拟了引力,你还记得我们当时是怎么做的吗?
PVector attract(Mover m) {
PVector force = PVector.sub(location,m.location);
float distance = force.mag();
distance = constrain(distance,5.0,25.0);
force.normalize();
float strength = (g mass m.mass) / (distance * distance);
force.mult(strength);
return force;
}
- 我们可以用Vec2重新实现同样的函数,并在Box2D中使用它。力的计算过程完全基于Box2D坐标,不需要任何像素坐标。
Vec2 attract(Mover m) {
Vec2 pos = body.getWorldCenter(); 首先我们要向Box2D询问位置
Vec2 moverPos = m.body.getWorldCenter();
Vec2 force = pos.sub(moverPos);
float distance = force.length();
distance = constrain(distance,1,5);
force.normalize();
float strength = (G * 1 m.body.m_mass) / (distance distance);
force.mulLocal(strength); 记住,在Box2D中,向量相乘的函数是mulLocal()
return force;
}
2、示例
鼠标风力