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((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, ); }