-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsensor.js
More file actions
132 lines (125 loc) · 4.63 KB
/
Copy pathsensor.js
File metadata and controls
132 lines (125 loc) · 4.63 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
class Sensor{
constructor(car){
this.car=car;
this.rayCount=5;
this.rayLength=100;
this.raySpread=Math.PI/2;
//angle by which rays spreads
this.rays=[];//keep the rays created
this.readings=[];// read borders for rays
}
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)
);//fills reading array with ray &respective border
}
}
#getReading(ray,roadBorders,traffic){
let touches=[];
for (let i=0;i<roadBorders.length;i++){
const touch=getIntersection(
// returns x,y & offset ie. distance b/w the ray & obstruction
ray[0],
ray[1],
roadBorders[i][0],
roadBorders[i][1]//these are input to getIntersection
);
if(touch){// if obstruction identified
touches.push(touch); // push returned values
}
}
for(let i=0;i<traffic.length;i++){
const poly=traffic[i].polygon;
for(let j=0;j<poly.length;j++){
const value=getIntersection(
ray[0],
ray[1],
poly[j],
poly[(j+1)%poly.length]
);
if(value){// if obstruction identified
touches.push(value); // push returned values
}
}
}
if(touches.length==0){
return null;
}
else{
const offsets=touches.map(e=>e.offset);
//make array of the returned offset values by all rays
const minOffset=Math.min(...offsets);
//take the most near obstruction offset value and return its coordinate
return touches.find(e=>e.offset==minOffset);
}
}
#castRays(){
this.rays=[];
for(let i=0;i<this.rayCount;i++){
const rayAngle=lerp(
// to create evenly distributed rays out of total raycount
// beatween the rayspread angle
this.raySpread/2,
-this.raySpread/2,
this.rayCount==1?0.5:i/(this.rayCount-1)
//when raycount is 1 ,single ray is equally divided 50% on either side of angle
//else if raycount is >1 it is divided uniformly in equal % b/w each rays
)+this.car.angle;//to change the ray angle along with car angle
const start={x:this.car.x,y:this.car.y};
//starting point of ray same as car coordinates
const end={
x:this.car.x-
Math.sin(rayAngle)*this.rayLength,
//subracting horizontal componet to limit ray end length
y:this.car.y-
Math.cos(rayAngle)*this.rayLength
//subtracting vertical comp to limit ray end length
};
this.rays.push([start,end]);
//filling the rays array
}
}
draw(ctx){
for(let i=0;i<this.rayCount;i++){
let end=this.rays[i][1];
//note: rays[i] is index representing different rays
// rays[i][0] is start coordinate of ray and rays[i][1] is end coordinate of ray
if(this.readings[i]){
end=this.readings[i];
//readings[i] has coordinate of nearest obstruction
}
ctx.beginPath();
ctx.lineWidth=2;
ctx.strokeStyle="yellow";
//note x and y changes by linear interpolation
ctx.moveTo(
this.rays[i][0].x,//for each ray index i start from car index
this.rays[i][0].y
);
ctx.lineTo(
end.x, //till nearest obstruction(if any) goes yellow ray
end.y
);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth=2;
ctx.strokeStyle="black";
//note x and y changes by linear interpolation
ctx.moveTo(
this.rays[i][1].x,//for each ray index i , black line start from ray end point
this.rays[i][1].y
);
ctx.lineTo(
end.x, // ray black line comes till the nearest obstruction(if any)
end.y
);
ctx.stroke();
}
}
}