55 lines
1.6 KiB
JavaScript
55 lines
1.6 KiB
JavaScript
"use strict"
|
|
const Vec2 = {
|
|
add({x:x1, y:y1}, {x:x2, y:y2}) {
|
|
return Object.freeze({x:x1+x2, y:y1+y2})
|
|
},
|
|
avg({x:x1, y:y1}, {x:x2, y:y2}) {
|
|
return Object.freeze({x:(x1+x2)/2, y:(y1+y2)/2})
|
|
},
|
|
fromPolar({x,y}, radius, angle) {
|
|
return Object.freeze({x: x + radius * Math.cos(angle),
|
|
y: y + radius * Math.sin(angle)})
|
|
},
|
|
sub({x:x1, y:y1}, {x:x2, y:y2}) {
|
|
return Object.freeze({x:x1-x2, y: y1-y2})
|
|
},
|
|
angle({x, y}) {
|
|
return Math.atan2(y, x)
|
|
},
|
|
len({x, y}) {
|
|
return Math.sqrt((x*x) + (y*y))
|
|
},
|
|
dist(a, b) {
|
|
return Vec2.len(Vec2.sub(a, b))
|
|
},
|
|
distLess(a, b, radius) {
|
|
const {x, y} = Vec2.sub(a, b)
|
|
return ((x*x) + (y*y)) < (radius * radius)
|
|
},
|
|
zero: Object.freeze({x:0, y:0})
|
|
};
|
|
|
|
function drawVertices(context, vertices, draw=true, close=true) {
|
|
if (draw) context.beginPath();
|
|
context.moveTo(vertices[0].x, vertices[0].y);
|
|
vertices.slice(1).forEach(({x, y}) =>
|
|
context.lineTo(x, y))
|
|
if (close) context.lineTo(vertices[0].x, vertices[0].y);
|
|
if (draw) context.stroke();
|
|
}
|
|
|
|
function convrgb(values) {
|
|
return 'rgb(' + values.map(x=>x|0).join(', ') + ')';
|
|
};
|
|
|
|
// apply mild noise on the sensor reading, and clamp between valid values
|
|
function gaussNoise(sigma=1) {
|
|
const x0 = 1.0 - Math.random();
|
|
const x1 = 1.0 - Math.random();
|
|
return sigma * Math.sqrt(-2 * Math.log(x0)) * Math.cos(2 * Math.PI * x1);
|
|
};
|
|
const zip = (arr, ...arrs) => {
|
|
return arr.map((val, i) => arrs.reduce((a, arr) => [...a, arr[i]], [val]));
|
|
}
|
|
const sum = (arr) => arr.reduce((a,b) => a+b)
|