概述
Chapter 2为我们介绍了力的相关概念、种类及这些力的原理,并且为我们提供了在Processing的绘制当中引入不同力的效果的方法,下面就让我们来好好的了解下这些有关力的知识,然后再让我们来发挥想象进行这些知识的运用创作。
原理介绍
力
说到力我们就会想到牛顿力学三定律,这为我们揭示了物体运动状态改变的原因——受到力的作用。而众所周知的是加速度和力成正比,和质量成反比。这意味着如果物体受一个推力作用产生运动,那么推力越大,运动越快(加速度越大);质量越大,运动越慢。
所以这样子就可以联系到我们上一章的内容,利用加速度将力融入到物体的自然运动变化当中 ,我们可以这样来写:
void applyForce(PVector force)
{
acceleration = force;
}
而我们同样也知道加速度a=F合/m,这让我们可以为一个物体添加多个力的作用,下面让我们来分别感受下不同种类的力在Processing中的使用:
摩擦力
摩擦力的方向,与物体运动的方向相反,我们可以给出这样的公式来定义摩擦力:F= -1×μ×Fn×v。在Processing中,我 们要先将速度向量单位化,再将单位向量乘以-1。
运行一下示例程序,感受一下,添加摩擦力的作用的过程:
//放在draw函数中
for (int i = 0; i < movers.length; i++)
{
PVector wind = new PVector(0.01, 0);
PVector gravity = new PVector(0, 0.1*movers[i].mass);
float c = 0.05;
PVector friction = movers[i].velocity.get();
friction.mult(-1);
friction.normalize();
friction.mult(c);
movers[i].applyForce(friction);
movers[i].applyForce(wind);
movers[i].applyForce(gravity);
movers[i].update();
movers[i].display();
movers[i].checkEdges();
}
运行一下:
Mover从产生到下降,游走之后,受到摩擦力作用,最终停下来。
引力(万有引力)
引力是最常见的力。我们都知道大名鼎鼎的万有引力公式:
之前我们研究了,给一个物体添加力的作用,现在,我们需要引入两个物体,为他们添加彼此之间力的作用,此处我们就引入了Attractor类。
在Processing中,作者甚至给出了,便于Mover和Attractor两者交互的办法:
将Mover对象传入Attractor对象的成员函数,返回引力向量。然后将引力向量传给 Mover对象的applyForce()函数。
动手实践——“引力散射”
我是这样构思的,随机在画布上生成一定数量的点,作为Mover对象,再以我们点击的点作为Attractor对象,产生引力效果之后,会有如同散射一般的感觉。
先来看看效果:
我参考了书上2-7模型,首先先构建Mover类:
class Mover {
PVector location;
PVector velocity;
PVector acceleration;
float mass;
Mover(float m, float x, float y) {
mass=m;
location=new PVector(x, y);
velocity=new PVector(0, 0);
acceleration=new PVector(0, 0);
}
void applyForce(PVector force) {
PVector f=PVector.div(force, mass);
acceleration.add(f);
}
void update() {
velocity.add(acceleration);
location.add(velocity);
acceleration.mult(0);
}
}
然后就是完成两个物体之间吸引的传递,就像我们在前文说的一样,将Mover对象传入Attractor对象的成员函数,返回引力向量。然后将引力向量传给 Mover对象的applyForce()函数。
Attractor类:
PVector location;
float G;
color Acolor;
Attractor() {
location=new PVector(mouseX,mouseY);
mass=20;
G=3;
}
PVector attract(Mover m) {
PVector force=PVector.sub(location, m.location);
float distance=force.mag();
force.normalize();
float strength=(G*mass*m.mass)/(distance*distance);
force.mult(strength);
return force;
}
//我在这里还加入了颜色选择,可以在mover变化时改变颜色
void colorchoice(){
int choice=int(random(0,3));
switch(choice)
{
case 0:
Acolor=color(0,103,78);
break;
case 1:
Acolor=color(6,109,224);
break;
case 2:
Acolor=color(58,197,255);
break;
}
}
}
主函数部分:
Mover[] m=new Mover[100];
Attractor[] a=new Attractor[10] ;
void setup() {
size(600, 600);
background(0);
for (int i=0; i<100; i++) {
m[i]=new Mover(1, random(width), random(height));
}
for (int i=0; i<10; i++) {
a[i]=new Attractor();
}
}
void mouseClicked(){
background(0);
for (int i=0; i<100; i++) {
m[i]=new Mover(1,random(width), random(height));
}
for (int i=0; i<10; i++) {
a[i]=new Attractor();
}
}
void draw() {
for (int j=0; j<10; j++) {
for (int i=0; i<100; i++) {
PVector force=a[j].attract(m[i]);
m[i].applyForce(force);
m[i].update();
}
a[j].colorchoice();
stroke(a[j].Acolor);
strokeWeight(3);
beginShape(POINTS);
//beginShape(LINES);
for (int i = 0; i < m.length-1; i++) {
vertex(m[i].location.x, m[i].location.y);
vertex(m[i+1].location.x, m[i+1].location.y);
}
endShape();
}
}
我最后还把画点,改成了连线,异想天开了下,结果居然,线条的感觉还有点令人惊喜。
心得
感觉引力部分已经很有意思了,但是,我的思维要枯竭了,马上就要做完了,开心的哭了起来。