You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
3.3 KiB
JavaScript

export const Vec2 = {
Mutate: {
add(target, [x, y]) {
target[0] += x;
target[1] += y;
return target;
},
scale(target, factor) {
target[0] *= factor;
target[1] *= factor;
return target;
},
normalize(target) {
const norm = Vec2.norm2([x, y]);
target[0] /= norm;
target[1] /= norm;
return target;
},
set(target, [x, y]) {
target[0] = x;
target[1] = y;
return target;
},
},
perpendicular([x, y]) {
return [-y, x];
},
distance2(v1, v2) {
return Vec2.norm2(Vec2.sub(v1, v2));
},
add([x1, y1], [x2, y2]) {
return [x1 + x2, y1 + y2];
},
sub([x1, y1], [x2, y2]) {
return [x1 - x2, y1 - y2];
},
dot([x1, y1], [x2, y2]) {
return x1 * x2 + y1 * y2;
},
scale([x, y], factor) {
return [x * factor, y * factor];
},
norm2([x, y]) {
return Math.sqrt(x ** 2 + y ** 2);
},
normalize([x, y]) {
const norm = Vec2.norm2([x, y]);
return [x / norm, y / norm];
},
findNearest(curve, pt) {
let index = -1;
let minDist = +Infinity;
for (let i = 0; i < curve.length; i++) {
const d = Vec2.distance2(curve[i], pt);
if (d < minDist) {
index = i;
minDist = d;
}
}
return [index, minDist];
},
};
export const Vec3 = {
Mutate: {
add(target, [x, y, z]) {
target[0] += x;
target[1] += y;
target[2] += z;
return target;
},
scale(target, factor) {
target[0] *= factor;
target[1] *= factor;
target[2] *= factor;
return target;
},
normalize(target) {
const norm = Vec3.norm2(target);
target[0] /= norm;
target[1] /= norm;
target[2] /= norm;
return target;
},
},
withMaxLength(v, max) {
const d = Vec3.norm2(v);
if (d > max) {
return Vec3.scale(v, max / d);
}
return v;
},
distance2(v1, v2) {
return Vec3.norm2(Vec3.sub(v1, v2));
},
add([x1, y1, z1], [x2, y2, z2]) {
return [x1 + x2, y1 + y2, z1 + z2];
},
sub([x1, y1, z1], [x2, y2, z2]) {
return [x1 - x2, y1 - y2, z1 - z2];
},
dot([x1, y1, z1], [x2, y2, z2]) {
return x1 * x2 + y1 * y2 + z1 * z2;
},
scale([x, y, z], factor) {
return [x * factor, y * factor, z * factor];
},
norm2([x, y, z]) {
return Math.sqrt(x ** 2 + y ** 2 + z ** 2);
},
normalize([x, y, z]) {
const norm = Vec3.norm2([x, y, z]);
return [x / norm, y / norm, z / norm];
},
findNearest(curve, pt) {
let index = -1;
let minDist = +Infinity;
for (let i = 0; i < curve.length; i++) {
const d = Vec3.distance2(curve[i], pt);
if (d < minDist) {
index = i;
minDist = d;
}
}
return [index, minDist];
},
};
export function clamp(min, value, max) {
return Math.min(max, Math.max(min, value));
}