Part2 为直线加上速度和重力的影响
接part1的单线程画线,今天要实现的内容是将part1实现的画线加上重力和速度的影响,使之符合现实生活
具体的实现形式是让单线程画出来的线像抛出一个小球那样,会进行坠落
原理
视频上连续物体状态,只是一种感觉。程序要画出图形在每一个时间点(比如以0.001ms)为间隔,在屏幕上的位置,我们看起来,就是一种连续的感觉。
模拟现实中物理运动状态,每一时间点上物理的位置,由运动所处的时间点、速度、重力加速度决定。这里我们采用的公式是欧拉方法(Euler method)。这个公式的运用就是实现一个粒子系统的关键所在。
位置矢量为、速度矢量为
、加速度矢量为
。
我们希望从时间的状态,计算下一个模拟时间
的状态。
如图,从A点到B点经过T时间,我们就需要计算出T时间中每一个点的位置,为了方便向量计算,定义Vec2f类,这个类的每一个对象,代表一个点;这个点可能是位置、速度或重力,只要给定了起始点,速度,重力三组值,套用如上公式,就可以计算出图形运动T时间中,每一步的位置
Vec2f类
package aline;
public class Vec2f {
public double x, y;
public Vec2f(double x, double y) {
this.x = x;
this.y = y;
}
// 向量加
public Vec2f add(Vec2f v) {
return new Vec2f(this.x + v.x, this.y + v.y);
}
// 向量乘
public Vec2f multiply(double f) {
return new Vec2f(this.x * f, this.y * f);
}
public void setX(double x){
this.x = x;
}
public void setY(double y){
this.y = y;
}
}
应用向量
修改之前part1的代码,将其监听器中的actionPerformed方法修改如下:
public void actionPerformed(ActionEvent e) {
Vec2f position = new Vec2f(100, 500); // 粒子的起始位置向量
Vec2f velocity = new Vec2f(100, -80); // 粒子的速度向量
Vec2f acceleration = new Vec2f(2, 20); // 粒子的重力向量
double dt = 0.1d; // 时间间隔量
for (int i = 0; i < 200; i++) {// 计算移动200步
position = position.add(velocity.multiply(dt)); // 下一位置(见公式)
velocity = velocity.add(acceleration.multiply(dt)); // 下一速度(见公式)
// 画到界面上
g.fillOval((int) position.x, (int) position.y, 10, 10);
try {
Thread.sleep(20);
} catch (Exception ef) {
}
}
}
运行结果
是不是很神奇
可以调节向量类中的参数实现不同的效果!
传送门:从粒子系统到群体智能 part1