homemanager-be/src/app-building/plan-renderer/renderer/renderer-utils.ts

108 lines
2.7 KiB
TypeScript

import { Line, Vec2, Vec2Box } from './renderer.interfaces';
export const vec2Length = ([x, y]: Vec2) => Math.abs(Math.sqrt(x * x + y * y));
export const vec2Add = ([x1, y1]: Vec2, [x2, y2]: Vec2): Vec2 => [
x1 + x2,
y1 + y2,
];
export const vec2Multiply = ([x1, y1]: Vec2, [x2, y2]: Vec2): Vec2 => [
x1 * x2,
y1 * y2,
];
export const vec2Sub = ([x1, y1]: Vec2, [x2, y2]: Vec2): Vec2 => [
x1 - x2,
y1 - y2,
];
export const vec2MultiplyScalar = ([x, y]: Vec2, scalar: number): Vec2 => [
x * scalar,
y * scalar,
];
export const vec2DivideScalar = ([x, y]: Vec2, scalar: number): Vec2 => [
x / scalar,
y / scalar,
];
export const vec2Normalize = (vec: Vec2): Vec2 =>
vec2DivideScalar(vec, vec2Length(vec));
export const vec2Distance = (vec1: Vec2, vec2: Vec2) =>
vec2Length(vec2Sub(vec2, vec1));
export const vec2InCircle = (circle: Vec2, point: Vec2, radius: number) =>
vec2Distance(circle, point) <= radius;
export const vec2Inverse = (vec: Vec2): Vec2 => vec2MultiplyScalar(vec, -1);
export const vec2Snap = ([x, y]: Vec2, snapScale: number): Vec2 =>
vec2MultiplyScalar(
[Math.round(x / snapScale), Math.round(y / snapScale)],
snapScale,
);
export const vec2Equals = ([x1, y1]: Vec2, [x2, y2]: Vec2) =>
x1 === x2 && y1 === y2;
export const vec2AngleFromOrigin = (
[x, y]: Vec2,
[ox, oy]: Vec2 = [0, 0],
): number => Math.atan2(y - oy, x - ox);
export const vec2PointFromAngle = (
angle: number,
[ox, oy]: Vec2 = [0, 0],
): Vec2 => [Math.cos(angle) + ox, Math.sin(angle) + oy];
export const deg2rad = (deg: number) => deg * (Math.PI / 180);
export const rad2deg = (rad: number) => rad * (180 / Math.PI);
export const randomNumber = (min: number, max: number) =>
Math.floor(Math.random() * (max - min + 1) + min);
export const boundingBox = (points: Vec2[], start: Vec2Box): Vec2Box => {
let minX = start[0][0];
let minY = start[0][1];
let maxX = start[1][0];
let maxY = start[1][1];
for (let i = 0; i < points.length; i++) {
if (points[i][0] > maxX) {
maxX = points[i][0];
}
if (points[i][0] < minX) {
minX = points[i][0];
}
if (points[i][1] > maxY) {
maxY = points[i][1];
}
if (points[i][1] < minY) {
minY = points[i][1];
}
}
return [
[minX, minY],
[maxX, maxY],
];
};
export const isValidVec2 = ([x, y]: Vec2) =>
x != null && y != null && !isNaN(x) && !isNaN(y);
export function extractLinePoints(line: Line) {
return line.segments
.reduce<Vec2[]>((list, segment) => {
if (segment.start) return [...list, segment.start, segment.end];
return [...list, segment.end];
}, [])
.filter(
(vec, index, arry) =>
arry.findIndex((point) => vec2Equals(point, vec)) === index,
);
}