书名:代码本色:用编程模拟自然系统
作者:Daniel Shiffman
译者:周晗彬
ISBN:978-7-115-36947-5
目录
3.2 角运动
1、公式
- 位置 = 位置 + 速度
- 速度 = 速度 + 加速度
- 角度 = 角度 + 角速度
- 角速度 = 角速度 + 角加速度
2、Mover对象添加角运动
把与角运动相关的变量加入到Mover类中。
class Mover {
PVector location; 位置(向量)
PVector velocity; 速度
PVector acceleration; 加速度
float mass; 质量
float angle = 0; 角度(标量)
float aVelocity = 0; 角速度
float aAcceleration = 0; 角加速度
3、在display()函数中旋转对象
为了得到最终的效果,我们还需要在display()函数中旋转对象。
void display() {
stroke(0);
fill(175,200);
rectMode(CENTER);
pushMatrix(); pushMatrix()和popMatrix()使图形的旋转不会影响程序的其他部分
translate(location.x,location.y); 将原点设为图形所在的位置
rotate(angle); 转过一定角度
rect(0,0,mass*16,mass*16);
popMatrix();
}
4、示例代码3-2
示例代码3-2 力和(随意)角运动的结合
Mover[] movers = new Mover[20];
Attractor a;
void setup() {
size(640,360);
background(255);
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover(random(0.1,2),random(width),random(height));
}
a = new Attractor();
}
void draw() {
background(255);
a.display();
for (int i = 0; i < movers.length; i++) {
PVector force = a.attract(movers[i]);
movers[i].applyForce(force);
movers[i].update();
movers[i].display();
}
}
Attractor.pde
class Attractor {
float mass; // Mass, tied to size
PVector position; // position
float g;
Attractor() {
position = new PVector(width/2, height/2);
mass = 20;
g = 0.4;
}
PVector attract(Mover m) {
PVector force = PVector.sub(position, m.position); // Calculate direction of force
float distance = force.mag(); // Distance between objects
distance = constrain(distance, 5.0, 25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects
force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction)
float strength = (g * mass * m.mass) / (distance * distance); // Calculate gravitional force magnitude
force.mult(strength); // Get force vector --> magnitude * direction
return force;
}
// Method to display
void display() {
stroke(0);
strokeWeight(2);
fill(227,0,0);
ellipse(position.x, position.y, 48, 48);
}
}
Mover.pde
class Mover {
PVector position;
PVector velocity;
PVector acceleration;
float mass;
color c;
float angle = 0;
float aVelocity = 0;
float aAcceleration = 0;
Mover(float m, float x, float y) {
mass = m;
position = new PVector(x,y);
velocity = new PVector(random(-1,1),random(-1,1));
acceleration = new PVector(0,0);
c = color(random(255),random(255),random(255));
}
void applyForce(PVector force) {
PVector f = PVector.div(force,mass);
acceleration.add(f);
}
void update() {
velocity.add(acceleration);
position.add(velocity);
aAcceleration = acceleration.x / 10.0;
aVelocity += aAcceleration;
aVelocity = constrain(aVelocity,-0.1,0.1);
angle += aVelocity;
acceleration.mult(0);
}
void display() {
stroke(0);
//fill(175,200);
fill(c);
rectMode(CENTER);
pushMatrix();
translate(position.x,position.y);
rotate(angle);
rect(0,0,mass*16,mass*16);
popMatrix();
}
}