1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
class Component {
constructor(radius, color, x, y, direction) {
this.rayLength = 100;
this.turnStepAmount = 0;
this.stepAmount = 5;
this.radius = radius;
this.x = x;
this.y = y;
this.direction = direction;
this.color = color;
this.fieldOfView = 180;
}
move(context) {
// this.direction += Math.random() * (2 * this.turnStepAmount) - this.turnStepAmount
this.direction = this.findNextRay(context);
var vector = this.detectionPoint(this.x, this.y, this.stepAmount, this.direction);
this.x = vector.x;
this.y = vector.y;
this.update(context);
}
buildRays() {
let rays = new Array();
let rayInteval = 10;
let noOfSteps = this.fieldOfView / rayInteval;
for (let i = 0; i < noOfSteps / 2; i++) {
if (i != 0) {
rays.push(rayInteval * -i);
}
rays.push(rayInteval * i);
}
return rays;
}
findNextRay(context) {
let rays = this.buildRays();
for (let i = 0; i < rays.length; i++) {
let tweakAngle = 0;
if (i == 0 && Math.random() > 0.95) {
tweakAngle = this.turnStepAmount * Math.random() * 5;
} else {
tweakAngle = rays[i] * Math.random() * 3;
}
let rayAngle = tweakAngle + this.direction + rays[i];
if (this.detectBox(context, context.canvas.width, context.canvas.height, rayAngle)) {
continue;
}
return rayAngle;
}
throw new Exception();
}
detectBox(context, width, height, direction) {
let perceptionVector = this.detectionPoint(this.x, this.y, this.rayLength, direction);
if (perceptionVector.x < 0 || perceptionVector.y < 0 || perceptionVector.x > width || perceptionVector.y > height) {
this.drawRay(context, perceptionVector.x, perceptionVector.y, this.perceptionDistance, direction)
return true;
}
return false;
}
update(context) {
this.updateBoid(context);
this.drawRay(context, this.x, this.y, this.rayLength, this.direction);
}
updateBoid(context) {
context.beginPath();
context.fillStyle = "blue";
context.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
context.stroke();
context.restore();
}
drawRay(context, x, y, perceptionDistance, direction) {
context.lineWidth = 1;
context.beginPath();
// this.lineToAngle(context, x, y, perceptionDistance, direction);
context.stroke();
context.restore();
}
lineToAngle(context, x1, y1, length, angle) {
angle *= Math.PI / 180;
var x2 = x1 + length * Math.cos(angle),
y2 = y1 + length * Math.sin(angle);
context.moveTo(x1, y1);
context.lineTo(x2, y2);
return {
x: x2,
y: y2
};
}
detectionPoint(x1, y1, length, angle) {
angle *= Math.PI / 180;
var x2 = x1 + length * Math.cos(angle),
y2 = y1 + length * Math.sin(angle);
return {
x: x2,
y: y2
};
}
}
|