书名:代码本色:用编程模仿自然体系
作者:Daniel Shiffman
译者:周晗彬
ISBN:978-7-115-36947-5
目次
2.9 引力
4、在Sketch中模仿引力
在示例代码2-1中,我们创建了一个简单的Mover对象,这个对象拥有位置、速率、加速率和applyForce()函数。
我们要继承用这个Mover类模仿引力,在Sketch中创建两个对象:
- 一个Mover对象;(Sketch 素描; 速写; 草图; 小品; 简报; 概述)
- 一个Attractor对象(实例化自一个全新的类,吸引器,它的位置是固定的)。
1)吸引器
如图2-9所示,Mover对象受Attractor对象产生的引力作用,引力方向指向Attractor对象。
我们可以简单地实现这个Attractor对象——给它一个位置、质量和绘制自身的函数(根据质量巨细确定表现巨细)。
class Attractor { float mass; Attractor对象很简单,它不会移动,只有质量和位置 PVector location; Attractor() { location = new PVector(width/2,height/2); mass = 20; }void display() { stroke(0); fill(175,200); ellipse(location.x,location.y,mass*2,mass*2); }}2)实例化
接着,我们在主步调中添加一个Attractor类的实例。
Mover m;Attractor a;void setup() { size(200,200); m = new Mover(); a = new Attractor(); 初始化Attractor对象}void draw() { background(255); a.display(); 表现Attractor对象 m.update(); m.display();}这是一个很好的步调结构:主步调中有一个Mover对象和一个Attractor对象,有两个类分别控制它们的变量和举动。另有一个题目,即我们怎样让两个对象交互:让此中一个对象吸引另一个对象?
5、两个对象交互
1)方法
下面列举了办理这个题目标几种方法(固然另有其他方法)。
方法函数1. 将Mover对象和Attractor对象同时传入一个函数attraction(a,m)2. 将Mover对象传入Attractor对象的成员函数a.attract(m)3. 将Attractor对象传入Mover对象的成员函数m.attractTo(a)4. 将Mover对象传入Attractor对象的成员函数,返回引力向量。然后将引力向量传给Mover对象的applyForce()函数PVector f=a.attract(m); m.applyForce(f);探索对象之间的各种交互方式是一种很好的编程实践,你可以接纳上面任何一种实现方式。
- 但对我来说,我起首会舍弃方法1,由于attraction()函数与两个对象都毫
无联系,这并不是一种面向对象的实现方式;
- 方法2可以表述为“Attractor对象吸引Mover对象”,
- 方法3可以表述为“Mover对象被Attractor对象吸引”,它们的区别只在于表述方式的差异;
- 方法4是我最喜好的实现方式,至少从本书的角度思量,我们最好接纳这种方法。
究竟,前面我们花了很多时间讨论applyForce()函数,继承利用这个函数会让代码显得清晰易懂。
2)实现
扼要地说,从前我们的实现方式是这样的:
PVector f = new PVector(0.1,0); 创建一个力向量m.applyForce(f);如今,我们要改成:
PVector f = a.attract(m); 两个对象之间的引力m.applyForce(f);因此,draw()函数如今被写成:
void draw() { background(255); PVector f = a.attract(m); 盘算引力,并把它作用在物体上 m.applyForce(f); m.update(); a.display(); m.display();}Attractor类有一个attract()函数,接下来我们要实现这个函数。这个函数的参数是一个Mover对象,返回值是一个向量对象:这个函数的内容就是实现引力公式。
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; 返回力,之后将它作用在对象上}3)小题目
差不多已经大功告成,但另有个小题目。
细致看上面的代码,你会发现有一个除法运算。只要有除法运算,我们都要问本身一个题目:要是对象之间的隔断很小,以致为零(环境更糟!)会发生什么?我们知道不能将一个数除以0,假如我们将一个数除以0.000 1,也等同于将它乘以10 000!引力公式是针对现实天下的,但如今我们在Processing的模仿天下里,这里并非现实天下。在以上Processing代码中,Mover对象大概与Attractor对象非常靠近,末了产生极大的引力,导致Mover对象飞出屏幕。
因此,我们最好思量引力公式的现实表现,将对象之间的隔断限定在现实大概的范围内。好比,无论Mover对象在什么位置,我们约定它和Attractor对象的隔断始终都不小于5像素,不大于25像素。
distance = constrain(distance,5,25);我们要限定对象之间的最小隔断,同理,最好也要限定它们的最大隔断。举个例子,假如Mover对象和Attractor对象之间的隔断是500像素(这是一个不公道的值),在盘算引力时,我们就必要除以250 000,末了求得的引力会变得很小,完全可以忽略不计。 |