Refactoring points

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
Mark Tolmacs 2024-09-20 21:32:32 +02:00
parent 8ca4cf3260
commit b4cb314090
No known key found for this signature in database
40 changed files with 746 additions and 783 deletions

View file

@ -5,6 +5,7 @@ import type {
Radians,
Degrees,
Vector,
ViewportPoint,
} from "./types";
import { PRECISION } from "./utils";
import { vectorFromPoint, vectorScale } from "./vector";
@ -16,7 +17,7 @@ import { vectorFromPoint, vectorScale } from "./vector";
* @param y The Y coordinate
* @returns The branded and created point
*/
export function point<Point extends GlobalPoint | LocalPoint>(
export function point<Point extends GlobalPoint | LocalPoint | ViewportPoint>(
x: number,
y: number,
): Point {
@ -29,9 +30,9 @@ export function point<Point extends GlobalPoint | LocalPoint>(
* @param numberArray The number array to check and to convert to Point
* @returns The point instance
*/
export function pointFromArray<Point extends GlobalPoint | LocalPoint>(
numberArray: number[],
): Point | undefined {
export function pointFromArray<
Point extends GlobalPoint | LocalPoint | ViewportPoint,
>(numberArray: number[]): Point | undefined {
return numberArray.length === 2
? point<Point>(numberArray[0], numberArray[1])
: undefined;
@ -43,9 +44,9 @@ export function pointFromArray<Point extends GlobalPoint | LocalPoint>(
* @param pair A number pair to convert to Point
* @returns The point instance
*/
export function pointFromPair<Point extends GlobalPoint | LocalPoint>(
pair: [number, number],
): Point {
export function pointFromPair<
Point extends GlobalPoint | LocalPoint | ViewportPoint,
>(pair: [number, number]): Point {
return pair as Point;
}
@ -55,9 +56,9 @@ export function pointFromPair<Point extends GlobalPoint | LocalPoint>(
* @param v The vector to convert
* @returns The point the vector points at with origin 0,0
*/
export function pointFromVector<P extends GlobalPoint | LocalPoint>(
v: Vector,
): P {
export function pointFromVector<
P extends GlobalPoint | LocalPoint | ViewportPoint,
>(v: Vector): P {
return v as unknown as P;
}
@ -67,7 +68,9 @@ export function pointFromVector<P extends GlobalPoint | LocalPoint>(
* @param p The value to attempt verification on
* @returns TRUE if the provided value has the shape of a local or global point
*/
export function isPoint(p: unknown): p is LocalPoint | GlobalPoint {
export function isPoint(
p: unknown,
): p is LocalPoint | GlobalPoint | ViewportPoint {
return (
Array.isArray(p) &&
p.length === 2 &&
@ -86,10 +89,9 @@ export function isPoint(p: unknown): p is LocalPoint | GlobalPoint {
* @param b Point The second point to compare
* @returns TRUE if the points are sufficiently close to each other
*/
export function pointsEqual<Point extends GlobalPoint | LocalPoint>(
a: Point,
b: Point,
): boolean {
export function pointsEqual<
Point extends GlobalPoint | LocalPoint | ViewportPoint,
>(a: Point, b: Point): boolean {
const abs = Math.abs;
return abs(a[0] - b[0]) < PRECISION && abs(a[1] - b[1]) < PRECISION;
}
@ -102,11 +104,9 @@ export function pointsEqual<Point extends GlobalPoint | LocalPoint>(
* @param angle The radians to rotate the point by
* @returns The rotated point
*/
export function pointRotateRads<Point extends GlobalPoint | LocalPoint>(
[x, y]: Point,
[cx, cy]: Point,
angle: Radians,
): Point {
export function pointRotateRads<
Point extends GlobalPoint | LocalPoint | ViewportPoint,
>([x, y]: Point, [cx, cy]: Point, angle: Radians): Point {
return point(
(x - cx) * Math.cos(angle) - (y - cy) * Math.sin(angle) + cx,
(x - cx) * Math.sin(angle) + (y - cy) * Math.cos(angle) + cy,
@ -121,11 +121,9 @@ export function pointRotateRads<Point extends GlobalPoint | LocalPoint>(
* @param angle The degree to rotate the point by
* @returns The rotated point
*/
export function pointRotateDegs<Point extends GlobalPoint | LocalPoint>(
point: Point,
center: Point,
angle: Degrees,
): Point {
export function pointRotateDegs<
Point extends GlobalPoint | LocalPoint | ViewportPoint,
>(point: Point, center: Point, angle: Degrees): Point {
return pointRotateRads(point, center, degreesToRadians(angle));
}
@ -143,8 +141,8 @@ export function pointRotateDegs<Point extends GlobalPoint | LocalPoint>(
*/
// TODO 99% of use is translating between global and local coords, which need to be formalized
export function pointTranslate<
From extends GlobalPoint | LocalPoint,
To extends GlobalPoint | LocalPoint,
From extends GlobalPoint | LocalPoint | ViewportPoint,
To extends GlobalPoint | LocalPoint | ViewportPoint,
>(p: From, v: Vector = [0, 0] as Vector): To {
return point(p[0] + v[0], p[1] + v[1]);
}
@ -156,8 +154,14 @@ export function pointTranslate<
* @param b The other point to create the middle point for
* @returns The middle point
*/
export function pointCenter<P extends LocalPoint | GlobalPoint>(a: P, b: P): P {
return point((a[0] + b[0]) / 2, (a[1] + b[1]) / 2);
export function pointCenter<P extends LocalPoint | GlobalPoint | ViewportPoint>(
...p: P[]
): P {
return pointFromPair(
p
.reduce((mid, x) => [mid[0] + x[0], mid[1] + x[1]], [0, 0])
.map((x) => x / p.length) as [number, number],
);
}
/**
@ -168,10 +172,9 @@ export function pointCenter<P extends LocalPoint | GlobalPoint>(a: P, b: P): P {
* @param b The other point to act like the vector to translate by
* @returns
*/
export function pointAdd<Point extends LocalPoint | GlobalPoint>(
a: Point,
b: Point,
): Point {
export function pointAdd<
Point extends LocalPoint | GlobalPoint | ViewportPoint,
>(a: Point, b: Point): Point {
return point(a[0] + b[0], a[1] + b[1]);
}
@ -183,10 +186,9 @@ export function pointAdd<Point extends LocalPoint | GlobalPoint>(
* @param b The point which will act like a vector
* @returns The resulting point
*/
export function pointSubtract<Point extends LocalPoint | GlobalPoint>(
a: Point,
b: Point,
): Point {
export function pointSubtract<
Point extends LocalPoint | GlobalPoint | ViewportPoint,
>(a: Point, b: Point): Point {
return point(a[0] - b[0], a[1] - b[1]);
}
@ -197,10 +199,9 @@ export function pointSubtract<Point extends LocalPoint | GlobalPoint>(
* @param b Second point
* @returns The euclidean distance between the two points.
*/
export function pointDistance<P extends LocalPoint | GlobalPoint>(
a: P,
b: P,
): number {
export function pointDistance<
P extends LocalPoint | GlobalPoint | ViewportPoint,
>(a: P, b: P): number {
return Math.hypot(b[0] - a[0], b[1] - a[1]);
}
@ -213,10 +214,9 @@ export function pointDistance<P extends LocalPoint | GlobalPoint>(
* @param b Second point
* @returns The euclidean distance between the two points.
*/
export function pointDistanceSq<P extends LocalPoint | GlobalPoint>(
a: P,
b: P,
): number {
export function pointDistanceSq<
P extends LocalPoint | GlobalPoint | ViewportPoint,
>(a: P, b: P): number {
return Math.hypot(b[0] - a[0], b[1] - a[1]);
}
@ -228,7 +228,9 @@ export function pointDistanceSq<P extends LocalPoint | GlobalPoint>(
* @param multiplier The scaling factor
* @returns
*/
export const pointScaleFromOrigin = <P extends GlobalPoint | LocalPoint>(
export const pointScaleFromOrigin = <
P extends GlobalPoint | LocalPoint | ViewportPoint,
>(
p: P,
mid: P,
multiplier: number,
@ -243,7 +245,9 @@ export const pointScaleFromOrigin = <P extends GlobalPoint | LocalPoint>(
* @param r The other point to compare against
* @returns TRUE if q is indeed between p and r
*/
export const isPointWithinBounds = <P extends GlobalPoint | LocalPoint>(
export const isPointWithinBounds = <
P extends GlobalPoint | LocalPoint | ViewportPoint,
>(
p: P,
q: P,
r: P,