📄 tij0187.html
字号:
<html><body>
<table width="100%"><tr>
<td>
<a href="http://www.bruceeckel.com/javabook.html">Bruce Eckel's Thinking in Java</a>
</td>
<td align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0186.html">Prev</a> | <a href="tij0188.html">Next</a>
</td>
</tr></table>
<hr>
<H2 ALIGN=LEFT>
Complexity
theory
<P><A NAME="Index3067"></A></H2>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
program was modified from code originally created by Larry O’Brien, and
is based on the “Boids” program created by Craig Reynolds in 1986
to demonstrate an aspect of complexity theory called “emergence.”
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
goal here is to produce a reasonably lifelike reproduction of <A NAME="Index3068"></A>flocking
or <A NAME="Index3069"></A><A NAME="Index3070"></A>herding
behavior in animals by establishing a small set of simple rules for each
animal. Each animal can look at the entire scene and all the other animals in
the scene, but it reacts
<a name="only"></a>only
to a set of nearby “flockmates.” The animal moves according to
three simple steering behaviors:
</FONT><P></DIV>
<OL>
<LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> Separation:
Avoid crowding local flockmates.
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> Alignment:
Follow the average heading of local flockmates.
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> Cohesion:
Move toward the center of the group of local flockmates.
</FONT></OL><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">More
elaborate models can include obstacles and the ability for the animals to
predict collisions and avoid them, so the animals can flow around fixed objects
in the environment. In addition, the animals might also be given a goal, which
can cause the herd to follow a desired path. For simplicity, obstacle avoidance
and goal-seeking is not included in the model presented here.
</FONT><P></DIV><DIV ALIGN=LEFT><A NAME="Index3071"></A><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Emergence
means that, despite the limited nature of computers and the simplicity of the
steering rules, the result seems realistic. That is, remarkably lifelike
behavior “emerges” from this simple model.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
program is presented as a combined application/applet:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: FieldOBeasts.java</font>
<font color="#009900">// Demonstration of complexity theory; simulates </font>
<font color="#009900">// herding behavior in animals. Adapted from</font>
<font color="#009900">// a program by Larry O'Brien lobrien@msn.com</font>
<font color="#0000ff">import</font> java.awt.*;
<font color="#0000ff">import</font> java.awt.event.*;
<font color="#0000ff">import</font> java.applet.*;
<font color="#0000ff">import</font> java.util.*;
<font color="#0000ff">class</font> Beast {
<font color="#0000ff">int</font>
x, y, <font color="#009900">// Screen position</font>
currentSpeed; <font color="#009900">// Pixels per second</font>
<font color="#0000ff">float</font> currentDirection; <font color="#009900">// Radians</font>
Color color; <font color="#009900">// Fill color</font>
FieldOBeasts field; <font color="#009900">// Where the Beast roams</font>
<font color="#0000ff">static</font> <font color="#0000ff">final</font> <font color="#0000ff">int</font> GSIZE = 10; <font color="#009900">// Graphic size</font>
<font color="#0000ff">public</font> Beast(FieldOBeasts f, <font color="#0000ff">int</font> x, <font color="#0000ff">int</font> y,
<font color="#0000ff">float</font> cD, <font color="#0000ff">int</font> cS, Color c) {
field = f;
<font color="#0000ff">this</font>.x = x;
<font color="#0000ff">this</font>.y = y;
currentDirection = cD;
currentSpeed = cS;
color = c;
}
<font color="#0000ff">public</font> <font color="#0000ff">void</font> step() {
<font color="#009900">// You move based on those within your sight:</font>
Vector seen = field.beastListInSector(<font color="#0000ff">this</font>);
<font color="#009900">// If you're not out in front</font>
<font color="#0000ff">if</font>(seen.size() > 0) {
<font color="#009900">// Gather data on those you see</font>
<font color="#0000ff">int</font> totalSpeed = 0;
<font color="#0000ff">float</font> totalBearing = 0.0f;
<font color="#0000ff">float</font> distanceToNearest = 100000.0f;
Beast nearestBeast =
(Beast)seen.elementAt(0);
Enumeration e = seen.elements();
<font color="#0000ff">while</font>(e.hasMoreElements()) {
Beast aBeast = (Beast) e.nextElement();
totalSpeed += aBeast.currentSpeed;
<font color="#0000ff">float</font> bearing =
aBeast.bearingFromPointAlongAxis(
x, y, currentDirection);
totalBearing += bearing;
<font color="#0000ff">float</font> distanceToBeast =
aBeast.distanceFromPoint(x, y);
<font color="#0000ff">if</font>(distanceToBeast < distanceToNearest) {
nearestBeast = aBeast;
distanceToNearest = distanceToBeast;
}
}
<font color="#009900">// Rule 1: Match average speed of those </font>
<font color="#009900">// in the list:</font>
currentSpeed = totalSpeed / seen.size();
<font color="#009900">// Rule 2: Move towards the perceived</font>
<font color="#009900">// center of gravity of the herd:</font>
currentDirection =
totalBearing / seen.size();
<font color="#009900">// Rule 3: Maintain a minimum distance </font>
<font color="#009900">// from those around you:</font>
<font color="#0000ff">if</font>(distanceToNearest <=
field.minimumDistance) {
currentDirection =
nearestBeast.currentDirection;
currentSpeed = nearestBeast.currentSpeed;
<font color="#0000ff">if</font>(currentSpeed > field.maxSpeed) {
currentSpeed = field.maxSpeed;
}
}
}
<font color="#0000ff">else</font> { <font color="#009900">// You are in front, so slow down</font>
currentSpeed =
(<font color="#0000ff">int</font>)(currentSpeed * field.decayRate);
}
<font color="#009900">// Make the beast move:</font>
x += (<font color="#0000ff">int</font>)(Math.cos(currentDirection)
* currentSpeed);
y += (<font color="#0000ff">int</font>)(Math.sin(currentDirection)
* currentSpeed);
x %= field.xExtent;
y %= field.yExtent;
<font color="#0000ff">if</font>(x < 0)
x += field.xExtent;
<font color="#0000ff">if</font>(y < 0)
y += field.yExtent;
}
<font color="#0000ff">public</font> <font color="#0000ff">float</font> bearingFromPointAlongAxis (
<font color="#0000ff">int</font> originX, <font color="#0000ff">int</font> originY, <font color="#0000ff">float</font> axis) {
<font color="#009900">// Returns bearing angle of the current Beast</font>
<font color="#009900">// in the world coordiante system</font>
<font color="#0000ff">try</font> {
<font color="#0000ff">double</font> bearingInRadians =
Math.atan(
(<font color="#0000ff">this</font>.y - originY) /
(<font color="#0000ff">this</font>.x - originX));
<font color="#009900">// Inverse tan has two solutions, so you </font>
<font color="#009900">// have to correct for other quarters:</font>
<font color="#0000ff">if</font>(x < originX) {
<font color="#0000ff">if</font>(y < originY) {
bearingInRadians += - (<font color="#0000ff">float</font>)Math.PI;
}
<font color="#0000ff">else</font> {
bearingInRadians =
(<font color="#0000ff">float</font>)Math.PI - bearingInRadians;
}
}
<font color="#009900">// Just subtract the axis (in radians):</font>
<font color="#0000ff">return</font> (<font color="#0000ff">float</font>) (axis - bearingInRadians);
} <font color="#0000ff">catch</font>(ArithmeticException aE) {
<font color="#009900">// Divide by 0 error possible on this</font>
<font color="#0000ff">if</font>(x > originX) {
<font color="#0000ff">return</font> 0;
}
<font color="#0000ff">else</font>
<font color="#0000ff">return</font> (<font color="#0000ff">float</font>) Math.PI;
}
}
<font color="#0000ff">public</font> <font color="#0000ff">float</font> distanceFromPoint(<font color="#0000ff">int</font> x1, <font color="#0000ff">int</font> y1){
<font color="#0000ff">return</font> (<font color="#0000ff">float</font>) Math.sqrt(
Math.pow(x1 - x, 2) +
Math.pow(y1 - y, 2));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -