@altpsyche/maths 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +51 -0
- package/dist/figure/animation.d.ts +29 -0
- package/dist/figure/animation.js +82 -0
- package/dist/figure/annotate.d.ts +55 -0
- package/dist/figure/annotate.js +53 -0
- package/dist/figure/extent.d.ts +62 -0
- package/dist/figure/extent.js +69 -0
- package/dist/figure/figure.d.ts +53 -0
- package/dist/figure/figure.js +75 -0
- package/dist/figure/mark.d.ts +66 -0
- package/dist/figure/mark.js +1 -0
- package/dist/figure/morph.d.ts +6 -0
- package/dist/figure/morph.js +117 -0
- package/dist/figure/node.d.ts +64 -0
- package/dist/figure/node.js +106 -0
- package/dist/figure/path.d.ts +56 -0
- package/dist/figure/path.js +142 -0
- package/dist/figure/timeline.d.ts +50 -0
- package/dist/figure/timeline.js +61 -0
- package/dist/figure/trim.d.ts +10 -0
- package/dist/figure/trim.js +100 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +26 -0
- package/dist/paint/canvas.d.ts +53 -0
- package/dist/paint/canvas.js +76 -0
- package/dist/paint/number.d.ts +1 -0
- package/dist/paint/number.js +16 -0
- package/dist/paint/svg.d.ts +64 -0
- package/dist/paint/svg.js +127 -0
- package/dist/timing/track.d.ts +37 -0
- package/dist/timing/track.js +85 -0
- package/dist/values/ease.d.ts +30 -0
- package/dist/values/ease.js +35 -0
- package/dist/values/mat3.d.ts +44 -0
- package/dist/values/mat3.js +63 -0
- package/dist/values/scalar.d.ts +21 -0
- package/dist/values/scalar.js +31 -0
- package/dist/values/vec2.d.ts +48 -0
- package/dist/values/vec2.js +82 -0
- package/dist/values/vec3.d.ts +27 -0
- package/dist/values/vec3.js +58 -0
- package/package.json +50 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The four curves a value can travel along between two moments.
|
|
3
|
+
*
|
|
4
|
+
* They are the whole of the shape a track can hold. A key is either flat where
|
|
5
|
+
* it sits or it is not, and two keys give four pairings: straight through,
|
|
6
|
+
* still at the start, still at the end, and still at both.
|
|
7
|
+
*
|
|
8
|
+
* Every one of them takes and returns zero to one, so a caller decides what the
|
|
9
|
+
* value at each end is and this decides only the pace between them.
|
|
10
|
+
*/
|
|
11
|
+
/** No easing at all: the value moves at one rate the whole way. */
|
|
12
|
+
export const linear = (along) => along;
|
|
13
|
+
/** Quadratic ease in: flat at the start, so the value leaves from rest and
|
|
14
|
+
* arrives at speed. */
|
|
15
|
+
export const easeIn = (along) => along * along;
|
|
16
|
+
/** Quadratic ease out: flat at the end, so the value leaves at speed and
|
|
17
|
+
* settles rather than stopping dead. */
|
|
18
|
+
export const easeOut = (along) => 1 - (1 - along) * (1 - along);
|
|
19
|
+
/** Smoothstep: the cubic that is flat at both ends, Ken Perlin. */
|
|
20
|
+
export const smoothstep = (along) => along * along * (3 - 2 * along);
|
|
21
|
+
/**
|
|
22
|
+
* The curve for a span whose ends are flat or not.
|
|
23
|
+
*
|
|
24
|
+
* This is the only place the four are chosen between, so a track and a figure's
|
|
25
|
+
* timeline pace a change the same way rather than each deciding for itself.
|
|
26
|
+
*/
|
|
27
|
+
export function curveFor(fromFlat, toFlat) {
|
|
28
|
+
if (fromFlat && toFlat)
|
|
29
|
+
return smoothstep;
|
|
30
|
+
if (fromFlat)
|
|
31
|
+
return easeIn;
|
|
32
|
+
if (toFlat)
|
|
33
|
+
return easeOut;
|
|
34
|
+
return linear;
|
|
35
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The transform a group of marks carries, and the one that maps a figure's own
|
|
3
|
+
* units onto whatever it is being drawn at.
|
|
4
|
+
*
|
|
5
|
+
* Nine numbers, column-major, matching the engine's layout: the first three are
|
|
6
|
+
* the first column rather than the first row, and the entry at flat index
|
|
7
|
+
* `col * 3 + row` is the one in that column and row. A flat picture needs only
|
|
8
|
+
* the top two rows, and the third exists so that a translation is a
|
|
9
|
+
* multiplication like every other move rather than an addition bolted on after.
|
|
10
|
+
*/
|
|
11
|
+
import type { Vec2 } from './vec2.js';
|
|
12
|
+
export type Mat3 = readonly [number, number, number, number, number, number, number, number, number];
|
|
13
|
+
/** Column-major product, so `multiply(a, b)` applies `b` to a point first and
|
|
14
|
+
* then `a`, which is the order a group's transform sits outside its child's. */
|
|
15
|
+
declare function multiply(a: Mat3, b: Mat3): Mat3;
|
|
16
|
+
/** The last column carries the offset, so this moves a point and leaves a
|
|
17
|
+
* direction where it was. */
|
|
18
|
+
declare function translation(v: Vec2): Mat3;
|
|
19
|
+
declare function scaling(v: Vec2): Mat3;
|
|
20
|
+
declare function rotation(radians: number): Mat3;
|
|
21
|
+
/** Applies the matrix to a point, which takes the translation with it. */
|
|
22
|
+
declare function transformPoint(m: Mat3, v: Vec2): Vec2;
|
|
23
|
+
/** Applies the rotation and scale and not the translation, which is what a
|
|
24
|
+
* direction wants: moving the picture must not move where an arrow points. */
|
|
25
|
+
declare function transformDirection(m: Mat3, v: Vec2): Vec2;
|
|
26
|
+
/**
|
|
27
|
+
* How much longer a length becomes under this transform.
|
|
28
|
+
*
|
|
29
|
+
* A stroke is given in figure units and drawn in pixels, and a transform that
|
|
30
|
+
* scales differently along each axis has no single answer, so this takes the
|
|
31
|
+
* mean of the two axes rather than pretending there is one.
|
|
32
|
+
*/
|
|
33
|
+
declare function scaleFactor(m: Mat3): number;
|
|
34
|
+
export declare const mat3: {
|
|
35
|
+
IDENTITY: Mat3;
|
|
36
|
+
multiply: typeof multiply;
|
|
37
|
+
translation: typeof translation;
|
|
38
|
+
scaling: typeof scaling;
|
|
39
|
+
rotation: typeof rotation;
|
|
40
|
+
transformPoint: typeof transformPoint;
|
|
41
|
+
transformDirection: typeof transformDirection;
|
|
42
|
+
scaleFactor: typeof scaleFactor;
|
|
43
|
+
};
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const IDENTITY = [1, 0, 0, 0, 1, 0, 0, 0, 1];
|
|
2
|
+
/** Column-major product, so `multiply(a, b)` applies `b` to a point first and
|
|
3
|
+
* then `a`, which is the order a group's transform sits outside its child's. */
|
|
4
|
+
function multiply(a, b) {
|
|
5
|
+
const [a0, a1, a2, a3, a4, a5, a6, a7, a8] = a;
|
|
6
|
+
const [b0, b1, b2, b3, b4, b5, b6, b7, b8] = b;
|
|
7
|
+
return [
|
|
8
|
+
a0 * b0 + a3 * b1 + a6 * b2,
|
|
9
|
+
a1 * b0 + a4 * b1 + a7 * b2,
|
|
10
|
+
a2 * b0 + a5 * b1 + a8 * b2,
|
|
11
|
+
a0 * b3 + a3 * b4 + a6 * b5,
|
|
12
|
+
a1 * b3 + a4 * b4 + a7 * b5,
|
|
13
|
+
a2 * b3 + a5 * b4 + a8 * b5,
|
|
14
|
+
a0 * b6 + a3 * b7 + a6 * b8,
|
|
15
|
+
a1 * b6 + a4 * b7 + a7 * b8,
|
|
16
|
+
a2 * b6 + a5 * b7 + a8 * b8,
|
|
17
|
+
];
|
|
18
|
+
}
|
|
19
|
+
/** The last column carries the offset, so this moves a point and leaves a
|
|
20
|
+
* direction where it was. */
|
|
21
|
+
function translation(v) {
|
|
22
|
+
return [1, 0, 0, 0, 1, 0, v.x, v.y, 1];
|
|
23
|
+
}
|
|
24
|
+
function scaling(v) {
|
|
25
|
+
return [v.x, 0, 0, 0, v.y, 0, 0, 0, 1];
|
|
26
|
+
}
|
|
27
|
+
function rotation(radians) {
|
|
28
|
+
const c = Math.cos(radians);
|
|
29
|
+
const s = Math.sin(radians);
|
|
30
|
+
return [c, s, 0, -s, c, 0, 0, 0, 1];
|
|
31
|
+
}
|
|
32
|
+
/** Applies the matrix to a point, which takes the translation with it. */
|
|
33
|
+
function transformPoint(m, v) {
|
|
34
|
+
const [m0, m1, , m3, m4, , m6, m7] = m;
|
|
35
|
+
return { x: m0 * v.x + m3 * v.y + m6, y: m1 * v.x + m4 * v.y + m7 };
|
|
36
|
+
}
|
|
37
|
+
/** Applies the rotation and scale and not the translation, which is what a
|
|
38
|
+
* direction wants: moving the picture must not move where an arrow points. */
|
|
39
|
+
function transformDirection(m, v) {
|
|
40
|
+
const [m0, m1, , m3, m4] = m;
|
|
41
|
+
return { x: m0 * v.x + m3 * v.y, y: m1 * v.x + m4 * v.y };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* How much longer a length becomes under this transform.
|
|
45
|
+
*
|
|
46
|
+
* A stroke is given in figure units and drawn in pixels, and a transform that
|
|
47
|
+
* scales differently along each axis has no single answer, so this takes the
|
|
48
|
+
* mean of the two axes rather than pretending there is one.
|
|
49
|
+
*/
|
|
50
|
+
function scaleFactor(m) {
|
|
51
|
+
const [m0, m1, , m3, m4] = m;
|
|
52
|
+
return (Math.hypot(m0, m1) + Math.hypot(m3, m4)) / 2;
|
|
53
|
+
}
|
|
54
|
+
export const mat3 = {
|
|
55
|
+
IDENTITY,
|
|
56
|
+
multiply,
|
|
57
|
+
translation,
|
|
58
|
+
scaling,
|
|
59
|
+
rotation,
|
|
60
|
+
transformPoint,
|
|
61
|
+
transformDirection,
|
|
62
|
+
scaleFactor,
|
|
63
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one-dimensional arithmetic everything else here is built out of.
|
|
3
|
+
*
|
|
4
|
+
* These take and return plain numbers so that a vector, a colour channel and a
|
|
5
|
+
* uniform can all be walked by the same four lines rather than by three copies
|
|
6
|
+
* of them.
|
|
7
|
+
*/
|
|
8
|
+
/** Held inside the two bounds, whichever way round they are given. */
|
|
9
|
+
export declare function clamp(value: number, low: number, high: number): number;
|
|
10
|
+
/** Part way from one number to another, and past either end when `along` is
|
|
11
|
+
* outside zero to one. */
|
|
12
|
+
export declare function lerp(from: number, to: number, along: number): number;
|
|
13
|
+
/**
|
|
14
|
+
* How far along the span a value sits, which is `lerp` read backwards.
|
|
15
|
+
*
|
|
16
|
+
* A span of no width has no answer, so it reports the start rather than
|
|
17
|
+
* dividing by zero and handing back an infinity that spreads.
|
|
18
|
+
*/
|
|
19
|
+
export declare function inverseLerp(from: number, to: number, value: number): number;
|
|
20
|
+
/** The same position in a second span as it held in the first. */
|
|
21
|
+
export declare function remap(value: number, fromLow: number, fromHigh: number, toLow: number, toHigh: number): number;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one-dimensional arithmetic everything else here is built out of.
|
|
3
|
+
*
|
|
4
|
+
* These take and return plain numbers so that a vector, a colour channel and a
|
|
5
|
+
* uniform can all be walked by the same four lines rather than by three copies
|
|
6
|
+
* of them.
|
|
7
|
+
*/
|
|
8
|
+
/** Held inside the two bounds, whichever way round they are given. */
|
|
9
|
+
export function clamp(value, low, high) {
|
|
10
|
+
return low < high ? Math.min(Math.max(value, low), high) : Math.min(Math.max(value, high), low);
|
|
11
|
+
}
|
|
12
|
+
/** Part way from one number to another, and past either end when `along` is
|
|
13
|
+
* outside zero to one. */
|
|
14
|
+
export function lerp(from, to, along) {
|
|
15
|
+
return from + (to - from) * along;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* How far along the span a value sits, which is `lerp` read backwards.
|
|
19
|
+
*
|
|
20
|
+
* A span of no width has no answer, so it reports the start rather than
|
|
21
|
+
* dividing by zero and handing back an infinity that spreads.
|
|
22
|
+
*/
|
|
23
|
+
export function inverseLerp(from, to, value) {
|
|
24
|
+
if (from === to)
|
|
25
|
+
return 0;
|
|
26
|
+
return (value - from) / (to - from);
|
|
27
|
+
}
|
|
28
|
+
/** The same position in a second span as it held in the first. */
|
|
29
|
+
export function remap(value, fromLow, fromHigh, toLow, toHigh) {
|
|
30
|
+
return lerp(toLow, toHigh, inverseLerp(fromLow, fromHigh, value));
|
|
31
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export type Vec2 = {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
};
|
|
5
|
+
declare function makeVec2(x: number, y: number): Vec2;
|
|
6
|
+
declare function add(a: Vec2, b: Vec2): Vec2;
|
|
7
|
+
declare function sub(a: Vec2, b: Vec2): Vec2;
|
|
8
|
+
declare function scale(v: Vec2, s: number): Vec2;
|
|
9
|
+
declare function dot(a: Vec2, b: Vec2): number;
|
|
10
|
+
/** The z of the three-dimensional cross product, which is the signed area of
|
|
11
|
+
* the parallelogram and tells which side of `a` the vector `b` falls. */
|
|
12
|
+
declare function cross(a: Vec2, b: Vec2): number;
|
|
13
|
+
declare function length(v: Vec2): number;
|
|
14
|
+
declare function distance(a: Vec2, b: Vec2): number;
|
|
15
|
+
/** A zero-length vector normalises to zero rather than to not-a-number, so a
|
|
16
|
+
* degenerate direction leaves a mark where it was instead of removing it. */
|
|
17
|
+
declare function normalize(v: Vec2): Vec2;
|
|
18
|
+
/** Turned a quarter turn anticlockwise, which is the direction an arrow head
|
|
19
|
+
* and a line's thickness are both measured along. */
|
|
20
|
+
declare function perpendicular(v: Vec2): Vec2;
|
|
21
|
+
declare function rotate(v: Vec2, radians: number): Vec2;
|
|
22
|
+
/** The direction the vector points, anticlockwise from the positive x axis, in
|
|
23
|
+
* radians between minus pi and pi. */
|
|
24
|
+
declare function angle(v: Vec2): number;
|
|
25
|
+
declare function lerp(a: Vec2, b: Vec2, along: number): Vec2;
|
|
26
|
+
/**
|
|
27
|
+
* The constructor and the family under one name, so building a vector stays
|
|
28
|
+
* short and an import line says what these operate on.
|
|
29
|
+
*
|
|
30
|
+
* The magnitude is not called `length`: a function's own `length` is how many
|
|
31
|
+
* arguments it takes, it is not writable, and assigning one throws.
|
|
32
|
+
*/
|
|
33
|
+
export declare const vec2: typeof makeVec2 & {
|
|
34
|
+
ZERO: Vec2;
|
|
35
|
+
add: typeof add;
|
|
36
|
+
sub: typeof sub;
|
|
37
|
+
scale: typeof scale;
|
|
38
|
+
dot: typeof dot;
|
|
39
|
+
cross: typeof cross;
|
|
40
|
+
magnitude: typeof length;
|
|
41
|
+
distance: typeof distance;
|
|
42
|
+
normalize: typeof normalize;
|
|
43
|
+
perpendicular: typeof perpendicular;
|
|
44
|
+
rotate: typeof rotate;
|
|
45
|
+
angle: typeof angle;
|
|
46
|
+
lerp: typeof lerp;
|
|
47
|
+
};
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Points and directions on a flat picture.
|
|
3
|
+
*
|
|
4
|
+
* The shape is the one the engine already uses for its own vectors, named
|
|
5
|
+
* fields rather than a tuple, so that if the two libraries ever meet neither
|
|
6
|
+
* has to convert.
|
|
7
|
+
*/
|
|
8
|
+
import { lerp as lerpNumber } from './scalar.js';
|
|
9
|
+
function makeVec2(x, y) {
|
|
10
|
+
return { x, y };
|
|
11
|
+
}
|
|
12
|
+
function add(a, b) {
|
|
13
|
+
return { x: a.x + b.x, y: a.y + b.y };
|
|
14
|
+
}
|
|
15
|
+
function sub(a, b) {
|
|
16
|
+
return { x: a.x - b.x, y: a.y - b.y };
|
|
17
|
+
}
|
|
18
|
+
function scale(v, s) {
|
|
19
|
+
return { x: v.x * s, y: v.y * s };
|
|
20
|
+
}
|
|
21
|
+
function dot(a, b) {
|
|
22
|
+
return a.x * b.x + a.y * b.y;
|
|
23
|
+
}
|
|
24
|
+
/** The z of the three-dimensional cross product, which is the signed area of
|
|
25
|
+
* the parallelogram and tells which side of `a` the vector `b` falls. */
|
|
26
|
+
function cross(a, b) {
|
|
27
|
+
return a.x * b.y - a.y * b.x;
|
|
28
|
+
}
|
|
29
|
+
function length(v) {
|
|
30
|
+
return Math.sqrt(dot(v, v));
|
|
31
|
+
}
|
|
32
|
+
function distance(a, b) {
|
|
33
|
+
return length(sub(a, b));
|
|
34
|
+
}
|
|
35
|
+
/** A zero-length vector normalises to zero rather than to not-a-number, so a
|
|
36
|
+
* degenerate direction leaves a mark where it was instead of removing it. */
|
|
37
|
+
function normalize(v) {
|
|
38
|
+
const len = length(v);
|
|
39
|
+
if (len === 0)
|
|
40
|
+
return { x: 0, y: 0 };
|
|
41
|
+
return scale(v, 1 / len);
|
|
42
|
+
}
|
|
43
|
+
/** Turned a quarter turn anticlockwise, which is the direction an arrow head
|
|
44
|
+
* and a line's thickness are both measured along. */
|
|
45
|
+
function perpendicular(v) {
|
|
46
|
+
return { x: -v.y, y: v.x };
|
|
47
|
+
}
|
|
48
|
+
function rotate(v, radians) {
|
|
49
|
+
const c = Math.cos(radians);
|
|
50
|
+
const s = Math.sin(radians);
|
|
51
|
+
return { x: v.x * c - v.y * s, y: v.x * s + v.y * c };
|
|
52
|
+
}
|
|
53
|
+
/** The direction the vector points, anticlockwise from the positive x axis, in
|
|
54
|
+
* radians between minus pi and pi. */
|
|
55
|
+
function angle(v) {
|
|
56
|
+
return Math.atan2(v.y, v.x);
|
|
57
|
+
}
|
|
58
|
+
function lerp(a, b, along) {
|
|
59
|
+
return { x: lerpNumber(a.x, b.x, along), y: lerpNumber(a.y, b.y, along) };
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The constructor and the family under one name, so building a vector stays
|
|
63
|
+
* short and an import line says what these operate on.
|
|
64
|
+
*
|
|
65
|
+
* The magnitude is not called `length`: a function's own `length` is how many
|
|
66
|
+
* arguments it takes, it is not writable, and assigning one throws.
|
|
67
|
+
*/
|
|
68
|
+
export const vec2 = Object.assign(makeVec2, {
|
|
69
|
+
ZERO: makeVec2(0, 0),
|
|
70
|
+
add,
|
|
71
|
+
sub,
|
|
72
|
+
scale,
|
|
73
|
+
dot,
|
|
74
|
+
cross,
|
|
75
|
+
magnitude: length,
|
|
76
|
+
distance,
|
|
77
|
+
normalize,
|
|
78
|
+
perpendicular,
|
|
79
|
+
rotate,
|
|
80
|
+
angle,
|
|
81
|
+
lerp,
|
|
82
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type Vec3 = {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
z: number;
|
|
5
|
+
};
|
|
6
|
+
declare function makeVec3(x: number, y: number, z: number): Vec3;
|
|
7
|
+
declare function add(a: Vec3, b: Vec3): Vec3;
|
|
8
|
+
declare function sub(a: Vec3, b: Vec3): Vec3;
|
|
9
|
+
declare function scale(v: Vec3, s: number): Vec3;
|
|
10
|
+
declare function dot(a: Vec3, b: Vec3): number;
|
|
11
|
+
declare function cross(a: Vec3, b: Vec3): Vec3;
|
|
12
|
+
declare function length(v: Vec3): number;
|
|
13
|
+
/** A zero-length vector normalises to zero rather than to not-a-number. */
|
|
14
|
+
declare function normalize(v: Vec3): Vec3;
|
|
15
|
+
declare function lerp(a: Vec3, b: Vec3, along: number): Vec3;
|
|
16
|
+
export declare const vec3: typeof makeVec3 & {
|
|
17
|
+
ZERO: Vec3;
|
|
18
|
+
add: typeof add;
|
|
19
|
+
sub: typeof sub;
|
|
20
|
+
scale: typeof scale;
|
|
21
|
+
dot: typeof dot;
|
|
22
|
+
cross: typeof cross;
|
|
23
|
+
magnitude: typeof length;
|
|
24
|
+
normalize: typeof normalize;
|
|
25
|
+
lerp: typeof lerp;
|
|
26
|
+
};
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Points and directions in space, for the values a figure carries that are not
|
|
3
|
+
* positions on the page, such as a colour or a direction being explained.
|
|
4
|
+
*
|
|
5
|
+
* The names and the shape match the engine's own vectors exactly, so the two
|
|
6
|
+
* can be merged later without either side converting.
|
|
7
|
+
*/
|
|
8
|
+
import { lerp as lerpNumber } from './scalar.js';
|
|
9
|
+
function makeVec3(x, y, z) {
|
|
10
|
+
return { x, y, z };
|
|
11
|
+
}
|
|
12
|
+
function add(a, b) {
|
|
13
|
+
return { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
|
|
14
|
+
}
|
|
15
|
+
function sub(a, b) {
|
|
16
|
+
return { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z };
|
|
17
|
+
}
|
|
18
|
+
function scale(v, s) {
|
|
19
|
+
return { x: v.x * s, y: v.y * s, z: v.z * s };
|
|
20
|
+
}
|
|
21
|
+
function dot(a, b) {
|
|
22
|
+
return a.x * b.x + a.y * b.y + a.z * b.z;
|
|
23
|
+
}
|
|
24
|
+
function cross(a, b) {
|
|
25
|
+
return {
|
|
26
|
+
x: a.y * b.z - a.z * b.y,
|
|
27
|
+
y: a.z * b.x - a.x * b.z,
|
|
28
|
+
z: a.x * b.y - a.y * b.x,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function length(v) {
|
|
32
|
+
return Math.sqrt(dot(v, v));
|
|
33
|
+
}
|
|
34
|
+
/** A zero-length vector normalises to zero rather than to not-a-number. */
|
|
35
|
+
function normalize(v) {
|
|
36
|
+
const len = length(v);
|
|
37
|
+
if (len === 0)
|
|
38
|
+
return { x: 0, y: 0, z: 0 };
|
|
39
|
+
return scale(v, 1 / len);
|
|
40
|
+
}
|
|
41
|
+
function lerp(a, b, along) {
|
|
42
|
+
return {
|
|
43
|
+
x: lerpNumber(a.x, b.x, along),
|
|
44
|
+
y: lerpNumber(a.y, b.y, along),
|
|
45
|
+
z: lerpNumber(a.z, b.z, along),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export const vec3 = Object.assign(makeVec3, {
|
|
49
|
+
ZERO: makeVec3(0, 0, 0),
|
|
50
|
+
add,
|
|
51
|
+
sub,
|
|
52
|
+
scale,
|
|
53
|
+
dot,
|
|
54
|
+
cross,
|
|
55
|
+
magnitude: length,
|
|
56
|
+
normalize,
|
|
57
|
+
lerp,
|
|
58
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@altpsyche/maths",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "The mathematics AltPsyche's figures are drawn from: vectors, matrices, curves, and a value walked over time.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Siva",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/altpsyche/altpsyche-maths.git"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/altpsyche/altpsyche-maths",
|
|
12
|
+
"bugs": "https://github.com/altpsyche/altpsyche-maths/issues",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"maths",
|
|
15
|
+
"animation",
|
|
16
|
+
"easing",
|
|
17
|
+
"keyframes",
|
|
18
|
+
"vector",
|
|
19
|
+
"matrix"
|
|
20
|
+
],
|
|
21
|
+
"type": "module",
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"main": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"default": "./dist/index.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"LICENSE",
|
|
34
|
+
"README.md"
|
|
35
|
+
],
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsc -p tsconfig.build.json",
|
|
38
|
+
"test": "vitest run",
|
|
39
|
+
"type-check": "tsc --noEmit -p tsconfig.json",
|
|
40
|
+
"prepack": "npm run build"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/node": "^20.19.43",
|
|
44
|
+
"typescript": "^5.9.3",
|
|
45
|
+
"vitest": "^4.0.17"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=20"
|
|
49
|
+
}
|
|
50
|
+
}
|