Repository navigation
Expand file tree
/
Copy pathsensor.js
More file actions
136 lines (122 loc) · 3.73 KB
/
Copy pathsensor.js
File metadata and controls
136 lines (122 loc) · 3.73 KB
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
129
130
131
132
133
134
135
136
class Sensor{
constructor(car){
this.car = car;
this.rayCount = 8;
this.rayLength = 150;
this.raySpread = Math.PI/2; // 90 degrees
this.rays = [];
// To detect how far away from borders or obstacles
this.readings= [];
}
draw(context){
for(let i=0; i<this.rayCount; i++){
// Sensor Rays Readings
let end= this.rays[i][1];
if(this.readings[i]){
end = this.readings[i];
}
// Draw Detecting Sensor Rays
context.beginPath();
context.lineWidth = 2;
context.strokeStyle = 'yellow';
context.moveTo(
this.rays[i][0].x,
this.rays[i][0].y
);
context.lineTo(
end.x,
end.y
);
context.stroke();
// Draw Intersecting Sensor Rays
context.beginPath();
context.lineWidth = 2;
context.strokeStyle = 'red';
context.moveTo(
this.rays[i][1].x,
this.rays[i][1].y
);
context.lineTo(
end.x,
end.y
);
context.stroke();
}
}
update(roadBorders, traffic){
this.#castRays();
this.readings = [];
for(let i=0; i<this.rays.length; i++){
this.readings.push(
this.#getReading(
this.rays[i],
roadBorders,
traffic
)
);
}
}
#getReading(ray, roadBorders, traffic){
let touches = [];
// Check offset distance from road borders
for(let i=0; i<roadBorders.length; i++){
const touch = getIntersection(
ray[0],
ray[1],
roadBorders[i][0],
roadBorders[i][1]
);
if(touch){
touches.push(touch);
}
}
// Check offset distance from traffic dummy cars
for(let i=0; i<traffic.length; i++){
const dummyPoly = traffic[i].polygon;
for(let j=0; j<dummyPoly.length; j++){
const touch = getIntersection(
ray[0],
ray[1],
dummyPoly[j],
dummyPoly[(j+1)%dummyPoly.length]
);
if(touch){
touches.push(touch);
}
}
}
// If rays touch nothing, return null
if(touches.length == 0){
return null;
}
else{
// If rays touch something, return the closest touch
const offsets = touches.map(e=>e.offset);
const minOffset = Math.min(...offsets); // Spread array into individual elements
return touches.find(e=>e.offset == minOffset);
}
}
#castRays(){
this.rays = [];
for(let i=0; i<this.rayCount; i++){
const rayAngle = lerp(
this.raySpread/2,
-this.raySpread/2,
this.rayCount == 1 ? 0.5 : i/(this.rayCount-1)
)+this.car.angle;
// Locate the car position &
// Rotate the ray angle by the car angle
const start = {
x: this.car.x,
y: this.car.y
};
const end = {
x: this.car.x -
Math.sin(rayAngle) * this.rayLength,
y: this.car.y -
Math.cos(rayAngle) * this.rayLength
};
this.rays.push([start,end]);
}
}
}