zz85在这里用简朴的代码就天生了一张随机的都市舆图。天生舆图与画一棵随机的树十分相似,都是先给出初始的元素,每一个元素在满足前提时会天生新的子代,末了由一切的元素配合组成了我们想要的舆图或树。
顺序中建立的几个对象
舆图中的每一条途径对应顺序中的一个Boid对象,Boid对象顶用两个向量离别示意途径的出发点和尽头坐标。顺序中的向量是运用 Three.js 这个库中的Vector2
对象来示意的。
// 运用three.js中的向量来示意
this.start = new THREE.Vector2(x, y);
this.end = new THREE.Vector2(x, y);
Boid对象另有这些属性:
x,y
:途径上间隔出发点最远的坐标angle
:途径的角度,会在其父代角度基础上偏转一个随机的角度distance
:这条途径的长度dead
:对象是不是已殒命
Boid另有一个update
要领,它有以下的几个功用:
更新 x,y 坐标
this.distance += 2;
x = this.start.x + this.distance * this.dx;
y = this.start.y + this.distance * this.dy;
this.end.set(x, y);检测订交状况,依据更新后的坐标作图。
在顺序中须要建立两个数组用于保留Boid
对象,boids
中寄存当前存活的元素,all_boids
寄存一切(包含存活和殒命)的元素。发生一个新元素时,会被同时放入两个数组,当元素殒命后,将其从boids
中移除。
关于一条途径A,它会一向向前延长,直到与另一条途径订交,这时候将A的状况设置为dead。为了检测订交,须要对all_boids
数组中的元素举行遍历。假如与个中的元素B涌现了交点,多是以下几种状况:
A是B的子代
B是A的子代
B的尽头在A上
A在延长历程当中遇上了B
这末了一种状况才是我们所须要的,将交点坐标赋给A的尽头,将A从boids数组中删去。以上搜检交点的历程发生在update()函数中。
最先构建顺序
在顺序最先时,起首建立四个元夙来示意画面的边框。
var b1 = new Boid();
var b2 = new Boid();
var b3 = new Boid();
var b4 = new Boid();
b1.dead = b2.dead = b3.dead = b4.dead = true;
b1.start.set(0, 0);
b2.start.set(width, 0);
b3.start.set(width, height);
b4.start.set(0, height);
b1.end = b2.start;
b2.end = b3.start;
b3.end = b4.start;
b4.end = b1.start;
all_boids.push(b1);
all_boids.push(b2);
all_boids.push(b3);
all_boids.push(b4);
然后建立第一个boid
,它的坐标在画面的中心
var b = new Boid(width/2, height/2, Math.random() * 2 * Math.PI);
boids.push(b);
all_boids.push(b);
挪用setInterval
函数进入轮回,起首搜检boids.length
,假如当前没有存活的boid
,则退出轮回,顺序完成。不然遍历一切存活的Boid
,更新其状况。在满足以下的几个前提时天生子代。
没有殒命
只要0.1的几率发生子代
当前一切存活元素的数目小于50
for (i = 0; i < boids.length; i++) {
var b = boids[i]; b.update(); // 发生子代的几个前提: // 1. 没有殒命 // 2. 只要0.1的几率发生子代 // 3. 当前一切存活元素的数目小于50 if (!b.dead && Math.random()>0.9 && boids.length < 50) { var child = new Boid(b.end.x, b.end.y, b.angle + Math.PI * (Math.random() > 0.5 ? 0.5 : -0.5)); child.parent = b; // child.fillStyle = getRndColor(); boids.push(child); all_boids.push(child); }
}
终究当存活的Boid数目为零时,顺序运转终了,就得到了一张随机的都市途径舆图。固然,如今的舆图还只是 2D 的版本,想天生 3D 的都市,能够检察下面的参考资料中zz85的博客。
代码及演示
在线的 demo
参考资料
本文原宣布在我的博客上。