File size: 2,877 Bytes
8fff5f7 |
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 |
class Sensor{
constructor(){
this.rayCount=5;
this.rayLength=150;
this.raySpread=Math.PI/4;
this.rays=[];
this.readings=[];
}
update(x,y,angle,roadBorders,traffic){
this.#castRays(x,y,angle);
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=[];
roadBorders.forEach(border => {
for(let i=1;i<border.length;i++){
const touch=getIntersection(
ray[0],
ray[1],
border[i-1],
border[i]
);
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;
}else{
const offsets=touches.map(e=>e.offset);
const minOffset=Math.min(...offsets);
return touches.find(e=>e.offset==minOffset);
}
}
#castRays(x,y,angle){
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)
)+angle;
const start={x,y};
const end={
x:x-Math.sin(rayAngle)*this.rayLength,
y: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.strokeStyle="black";
ctx.moveTo(
this.rays[i][1].x,
this.rays[i][1].y
);
ctx.lineTo(
end.x,
end.y
);
ctx.stroke();*/
}
}
} |