96 lines
2.2 KiB
JavaScript
96 lines
2.2 KiB
JavaScript
class Sensor {
|
|
constructor(car) {
|
|
this.car = car;
|
|
this.rayCount = 5;
|
|
this.rayLength = 150;
|
|
this.raySpread = Math.PI / 2;
|
|
|
|
this.rays = [];
|
|
this.readings = [];
|
|
}
|
|
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 = [];
|
|
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);
|
|
}
|
|
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) touches.push(value);
|
|
}
|
|
}
|
|
if (touches.length == 0) return null;
|
|
const offsets = touches.map((e) => e.offset);
|
|
const minOffset = Math.min(...offsets);
|
|
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;
|
|
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]);
|
|
}
|
|
}
|
|
draw(ctx) {
|
|
for (let i = 0; i < this.rayCount; i++) {
|
|
let end = this.rays[i][1];
|
|
if (this.readings[i]) end = this.readings[i];
|
|
|
|
ctx.beginPath();
|
|
ctx.lineWidth = 2;
|
|
ctx.strokeStyle = "yellow";
|
|
ctx.moveTo(this.rays[i][0].x, this.rays[i][0].y);
|
|
ctx.lineTo(end.x, end.y);
|
|
ctx.stroke();
|
|
|
|
ctx.beginPath();
|
|
ctx.lineWidth = 2;
|
|
ctx.strokeStyle = "black";
|
|
ctx.moveTo(this.rays[i][1].x, this.rays[i][1].y);
|
|
ctx.lineTo(end.x, end.y);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
}
|