80.JAVA编程思想——复杂性理论

80.JAVA编程思想——复杂性理论

下面要介绍的程序的前身是由Larry O‘Brien 原创的一些代码,并以由Craig Reynolds 于1986 年编制的“Boids”程序为基础,当时是为了演示复杂性理论的一个特殊问题,名为“凸显”(Emergence)。这儿要达到的目标是通过为每种动物都规定少许简单的规则,从而逼真地再现动物的群聚行为。每个动物都能看到看到整个环境以及环境中的其他动物,但它只与一系列附近的“群聚伙伴”打交道。动物的移动基于三个简单的引导行为:

(1) 分隔:避免本地群聚伙伴过于拥挤。

(2) 方向:遵从本地群聚伙伴的普遍方向。

(3) 聚合:朝本地群聚伙伴组的中心移动。

更复杂的模型甚至可以包括障碍物的因素,动物能预知和避免与障碍冲突的能力,所以它们能围绕环境中的固定物体自由活动。除此以外,动物也可能有自己的特殊目标,这也许会造成群体按特定的路径前进。为简化讨论,避免障碍以及目标搜寻的因素并未包括到这里建立的模型中。尽管计算机本身比较简陋,而且采用的规则也相当简单,但结果看起来是真实的。也就是说,相当逼真的行为从这个简单的模型中“凸显”出来了。

程序以合成到一起的应用程序/程序片的形式提供:

1     代码

import java.awt.*;

import java.awt.event.*;

import java.applet.*;

import java.util.*;

class Beast {

int
x, y,
// Screen position

currentSpeed;
// Pixels per second

float
currentDirection;//
Radians

Color color;
// Fill color

FieldOBeasts field;
// Where theBeast roams

static
finalintGSIZE
= 10;
// Graphic size

public Beast(FieldOBeasts
f, intx,
int
y, float
cD, int
cS, Color c) {

field =
f;

this.x =
x;

this.y =
y;

currentDirection =
cD;

currentSpeed =
cS;

color =
c;

}

public
void
step() {

// You move based on those within your sight:

Vector
seen = field.beastListInSector(this);

// If you‘re not out in front

if (seen.size() > 0) {

// Gather data on those you see

int
totalSpeed = 0;

float
totalBearing = 0.0f;

float
distanceToNearest = 100000.0f;

Beast nearestBeast = (Beast)
seen.elementAt(0);

Enumeration
e = seen.elements();

while (e.hasMoreElements()) {

Beast
aBeast = (Beast) e.nextElement();

totalSpeed +=
aBeast.currentSpeed;

float
bearing = aBeast.bearingFromPointAlongAxis(x,
y, currentDirection);

totalBearing +=
bearing;

float
distanceToBeast =
aBeast.distanceFromPoint(x,
y);

if (distanceToBeast <
distanceToNearest){

nearestBeast =
aBeast;

distanceToNearest =
distanceToBeast;

}

}

// Rule 1: Match average speed of those

// in the list:

currentSpeed =
totalSpeed / seen.size();

// Rule 2: Move towards the perceived

// center of gravity of the herd:

currentDirection =
totalBearing / seen.size();

// Rule 3: Maintain a minimum distance

// from those around you:

if (distanceToNearest <=
field.minimumDistance){

currentDirection =
nearestBeast.currentDirection;

currentSpeed =
nearestBeast.currentSpeed;

if (currentSpeed >
field.maxSpeed){

currentSpeed =
field.maxSpeed;

}

}

} else {
// You are infront, so slow down

currentSpeed = (int) (currentSpeed *
field.decayRate);

}

// Make the beast move:

x += (int) (Math.cos(currentDirection) *
currentSpeed);

y += (int) (Math.sin(currentDirection) *
currentSpeed);

x %=
field.xExtent;

y %=
field.yExtent;

if (x < 0)

x +=
field.xExtent;

if (y < 0)

y +=
field.yExtent;

}

public
float
bearingFromPointAlongAxis(int
originX,intoriginY,floataxis){

// Returns bearing angle of the current Beast

// in the world
coordiante system

try {

double
bearingInRadians = Math.atan((this.y -
originY) / (this.x -
originX));

// Inverse tan has two solutions, so you

// have to correct for other quarters:

if (x <
originX){

if (y <
originY){

bearingInRadians += -(float) Math.PI;

} else {

bearingInRadians = (float) Math.PI -
bearingInRadians;

}

}

// Just subtract the axis (in
radians):

return (float) (axis -
bearingInRadians);

} catch (ArithmeticException
aE) {

// Divide by 0 error possible on this

if (x >
originX){

return 0;

} else

return (float) Math.PI;

}

}

public
float
distanceFromPoint(int
x1,inty1){

return (float) Math.sqrt(Math.pow(x1 -
x, 2) + Math.pow(y1 -
y, 2));

}

public Point position() {

return
new
Point(x,
y);

}

// Beasts knowhow to draw themselves:

public
void
draw(Graphics
g) {

g.setColor(color);

int
directionInDegrees = (int)((currentDirection* 360) / (2 * Math.PI));

int
startAngle = directionInDegrees- FieldOBeasts.halfFieldOfView;

int
endAngle = 90;

g.fillArc(x,
y, GSIZE,GSIZE,startAngle,endAngle);

}

}

public
class
FieldOBeasts extends Applet
implements Runnable {

private
Vector beasts;

static
float
fieldOfView= (float)(Math.PI/ 4),
// In radians

// Deceleration % per second:

decayRate = 1.0f,
minimumDistance= 10f;
// In pixels

static
int
halfFieldOfView = (int)((fieldOfView* 360) / (2 * Math.PI)),
xExtent= 0, yExtent= 0,
numBeasts= 50,

maxSpeed = 20;
// Pixels/second

boolean
uniqueColors= true;

Thread thisThread;

int
delay= 25;

public
void
init() {

if (xExtent == 0 &&
yExtent == 0) {

xExtent = Integer.parseInt(getParameter("xExtent"));

yExtent = Integer.parseInt(getParameter("yExtent"));

}

beasts = makeBeastVector(numBeasts,
uniqueColors);

// Now start the beasts a-rovin‘:

thisThread =
new Thread(this);

thisThread.start();

}

public
void
run() {

while (true) {

for (int
i = 0; i <
beasts.size(); i++) {

Beast
b = (Beast) beasts.elementAt(i);

b.step();

}

try {

thisThread.sleep(delay);

} catch (InterruptedException
ex) {

}

repaint();
// Otherwise it won‘t update

}

}

Vector makeBeastVector(int
quantity, boolean
uniqueColors) {

Vector
newBeasts = new Vector();

Random generator =
new Random();

// Used only if uniqueColors is on:

double
cubeRootOfBeastNumber = Math.pow((double)
numBeasts, 1.0 / 3.0);

float
colorCubeStepSize = (float) (1.0 /
cubeRootOfBeastNumber);

float
r = 0.0f;

float
g = 0.0f;

float
b = 0.0f;

for (int
i = 0; i <
quantity; i++) {

int
x = (int)(generator.nextFloat()*
xExtent);

if (x >
xExtent - Beast.GSIZE)

x -= Beast.GSIZE;

int
y = (int)(generator.nextFloat()*
yExtent);

if (y >
yExtent - Beast.GSIZE)

y -= Beast.GSIZE;

float
direction = (float) (generator.nextFloat() * 2 * Math.PI);

int
speed = (int)(generator.nextFloat()* (float)maxSpeed);

if (uniqueColors) {

r +=
colorCubeStepSize;

if (r > 1.0) {

r -= 1.0f;

g +=
colorCubeStepSize;

if (g > 1.0) {

g -= 1.0f;

b += colorCubeStepSize;

if (b > 1.0)

b -= 1.0f;

}

}

}

newBeasts.addElement(new Beast(this,
x, y,
direction,speed,
newColor(r,g,b)));

}

return
newBeasts;

}

public
Vector beastListInSector(Beast viewer) {

Vector
output = new Vector();

Enumeration
e = beasts.elements();

Beast aBeast = (Beast)
beasts.elementAt(0);

int
counter = 0;

while (e.hasMoreElements()) {

aBeast = (Beast)
e.nextElement();

if (aBeast !=
viewer){

Point p =
aBeast.position();

Point
v = viewer.position();

float
bearing = aBeast.bearingFromPointAlongAxis(v.x,
v.y,
viewer.currentDirection);

if (Math.abs(bearing) <
fieldOfView / 2)

output.addElement(aBeast);

}

}

return
output;

}

public
void
paint(Graphics
g){

Enumeration
e = beasts.elements();

while (e.hasMoreElements()) {

((Beast)
e.nextElement()).draw(g);

}

}

public
staticvoid
main(String[]
args){

FieldOBeasts
field = new FieldOBeasts();

field.xExtent = 640;

field.yExtent = 480;

Frame frame =
new Frame("Field ‘O Beasts");

// Optionally use a command-line argument

// for the sleep time:

if (args.length>= 1)

field.delay = Integer.parseInt(args[0]);

frame.addWindowListener(new WindowAdapter() {

public
void
windowClosing(WindowEvent
e) {

System.exit(0);

}

});

frame.add(field, BorderLayout.CENTER);

frame.setSize(640, 480);

field.init();

field.start();

frame.setVisible(true);

}

} /// :~

尽管这并非对Craig Reynold 的“Boids”例子中的行为完美重现,但它却展现出了自己独有的迷人之外。通过对数字进行调整,即可进行全面的修改。

2     总结

通过学习,大家知道运用Java 可做到一些较复杂的事情。通过这些例子亦可看出,尽管Java 必定有自己的局限,但受那些局限影响的主要是性能(比如写好文字处理程序后,会发现C++的版本要快得多——这部分是由于IO 库做得不完善造成的;而在你读到本书的时候,情况也许已发生了变化。但Java 的局限也仅此而已,它在语言表达方面的能力是无以伦比的。利用Java,几乎可以表达出我们想得到的任何事情。而与此同时,Java 在表达的方便性和易读性上,也做足了功夫。所以在使用Java
时,一般不会陷入其他语言常见的那种复杂境地。使用那些语言时,会感觉它们象一个爱唠叨的老太婆,哪有Java 那样清纯、简练!而且通过Java 1.2 的JFC/Swing 库,AWT 的表达能力和易用性甚至又得到了进一步的增强。

时间: 2024-08-29 22:27:08

80.JAVA编程思想——复杂性理论的相关文章

《Java编程思想》第一二章

前段时间一直通过网络教程学习Java基础,把面向对象部分学完之后本来打算继续深入学习,但是感觉自己操之过急了,基础根本不够扎实,所以入手了一本<Java编程思想>,希望先把基础打好,再深入学习. 不得不说这本书真的不是浪得虚名,对于我这样的新手看完一二章之后也觉得这本书值得买了.跟网上教程不同,这本书一开始便直接全面深入论述Java面向对象编程中对对象的理解,值得注意的是如果之前没有Java编程的基础,第一章看起来会比较吃力,而且效果也不太好,因为都是理论没有使用代码进行演示说明,所以作者也支

1.JAVA 编程思想——对象入门

对象入门 欢迎转载,转载请标明出处:    http://blog.csdn.net/notbaron/article/details/51040219 如果学JAVA,没有读透<JAVA 编程思想>这本书,实在不好意思和别人说自己学过JAVA.鉴于此,蛤蟆忙里偷闲,偷偷翻看这本传说中的牛书. 面向对象编程OOP具有多方面吸引力.实现了更快和更廉价的开发与维护过程.对分析与设计人员,建模处理变得更加简单,能生成清晰.已于维护的设计方案. 这些描述看上去非常吸引人的,不过蛤蟆还是没啥印象(至少到

39.JAVA编程思想之外篇——JAVA图形化设计精简大全一文覆盖

39.JAVA编程思想之外篇--JAVA图形化设计精简大全一文覆盖 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/51204948 目录 Java图形化界面设计--容器(JFrame)...1 Java基本类(JFC)...1 l     AWTAbstract Window Toolkit(AWT)抽象窗口工具包... 2 l     Swing包... 2 l     AWT和Swing的区别... 6 Swing基本框

java编程思想总结(三)

java编程思想总结(三) java编程思想总结是一个持续更新的系列,是本人对自己多年工作中使用到java的一个经验性总结,也是温故而知新吧,因为很多基础的东西过了这么多年,平时工作中用不到也会遗忘掉,所以看看书,上上网,查查资料,也算是记录下自己的笔记吧,过一段时间之后再来看看也是蛮不错的,也希望能帮助到正在学习的人们,本系列将要总结一下几点: 面向对象的编程思想 java的基本语法 一些有趣的框架解析 实战项目的整体思路 代码的优化以及性能调优的几种方案 整体项目的规划和视角 其它遗漏的东西

70.JAVA编程思想——Web应用

70.JAVA编程思想--Web应用 创建一个应用,令其在真实的Web 环境中运行,它将把Java 的优势表现得淋漓尽致.这个应用的一部分是在Web 服务器上运行的一个Java 程序,另一部分则是一个"程序片"或"小应用程序"(Applet),从服务器下载至浏览器(即"客户").这个程序片从用户那里收集信息,并将其传回Web 服务器上运行的应用程序.程序的任务非常简单:程序片会询问用户的E-mail 地址,并在验证这个地址合格后(没有包含空格,而

java编程思想笔记(第一章)

Alan Kay 第一个定义了面向对象的语言 1.万物皆对象 2.程序是对象的集合,他们彼此通过发送消息来调用对方. 3.每个对象都拥有由其他对象所构成的存储 4.每个对象都拥有其类型(TYpe) 5.某一特定类型的所有对象都可以接收同样的消息. Booch提出一种更简洁的描述: 对象拥有状态(state) 行为(behavior) 和标识(identity) 每个对象都有一个接口 每个对象都属于定义了特性和行为的某个类(特性可以理解为属性的状态,行为可以理解为method) 在面向对象的程序设

《Java编程思想》学习笔记(序言):从机电男到程序猿

为什么要写该篇? 那是我计划把这个写成一个系列,所以这是序言.Java编程还差两个月就两年了,我希望在这之前读完<Java编程思想>,对自己的知识的一个总结.该系列主要叙述我在读<Java编程思想>这本书的过程中的一些理解,我希望用最通俗易懂的语言,最真实的生活场景来表达我个人世界里的Java.如果你是初学者,可以跟随我一起阅读,我想一定会有些帮助. 话说在前头,这篇大部分纯属扯淡,没有所谓的干货!如果你实在无聊的蛋疼,可以瞅瞅,一个机电男变身程序猿的故事.大学学的机械专业,平时有

重学Java(一):与《Java编程思想》的不解之缘

说起来非常惭愧,我在 2008 年的时候就接触了 Java,但一直到现在(2018 年 10 月 10 日),基础知识依然非常薄弱.用一句话自嘲就是:十年 IT 老兵,Java 菜鸡一枚. 于是,我想,不如静下心来,重新读一遍那些经典的 Java 技术书,并且没读完一章就输出一篇原创技术文章.从哪一本开始呢?想了一想,还是从<Java 编程思想>开始吧!毕竟这本书赢得了全球程序员的广泛赞誉,从 Java 的基础语法到最高级特性,都能指导我们 Java 程序员轻松掌握. 记得刚上大学那会,就买了

异常笔记--java编程思想

开一个新的系列,主要记一些琐碎的重要的知识点,把书读薄才是目的...特点: 代码少,概念多... 1. 基本概念 异常是在当前环境下无法获得必要的信息来解决这个问题,所以就需要从当前环境跳出,就是抛出异常.抛出异常后发生的几件事: 1.在堆上创建异常对象. 2.当前的执行路径中止                                          3. 当前环境抛出异常对象的引用.                                         4. 异常处理机制接