模仿引力

计算机软件开发 2024-10-8 20:54:58 95 0 来自 中国
书名:代码本色:用编程模仿自然体系
作者: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,末了求得的引力会变得很小,完全可以忽略不计。
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-10-18 14:22, Processed in 0.160345 second(s), 32 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表