A collection of TypeScript-based math helpers 🚀

This project is a collection of TypeScript math helpers and utilities for the browser and Node.js. The modular approach allows to select only the required functions. It works well with all modern bundlers and supports tree shaking 🌲. The library is built using immutable/pure functions.
Table of contents
TypeScript Usage
To use the library with TypeScript, you need to install the module from npm:
npm install toolcool-math
The import any function like v2Sum:
import { v2Sum, Vector2 } from 'toolcool-math';
const v1: Vector2 = [1, 2];
const v2: Vector2 = [3, 4];
const sum = v2Sum(v1, v2);
Browser Usage
Any function can also be used in the browser using the tc-math.min.js file. All functions are located in the TCMath namespace:
<script src="tc-math.min.js"></script>
<script>
const sum = TCMath.v2Sum([1, 2], [3, 4]);
console.log(sum);
</script>
The library is also available on the jsDelivr CND:
<script src="https://cdn.jsdelivr.net/npm/toolcool-math/dist/tc-math.min.js"></script>
<script>
const sum = TCMath.v2Sum([1, 2], [3, 4]);
console.log(sum);
</script>
Node.js Usage
The library can also be used in Node.js.
npm install toolcool-math
const { setDecimalPlaces } = require('toolcool-math/dist/tc-math.node.cjs');
const rounded = setDecimalPlaces(Math.PI, 2);
console.log(rounded);
Vectors
There are the following types of vectors:
Vector2 for a 2D vector, Vector3 for a 3D vector, and Vector for the general case.
import { Vector2, Vector3, Vector4, Vector } from 'toolcool-math';
const v2: Vector2 = [1, 2];
const v3: Vector3 = [1, 2, 3];
const v4: Vector4 = [1, 2, 3, 4];
const v5: Vector = [1, 2, 3, 4, 5];
const v6: Vector = [1, 2, 3, 4, 5, 6];
Vectors Sum
The following functions are used to add vectors: v2Sum for a 2D vector, v3Sum for a 3D vector, and vSum for the general case. Each function receives an optional decimalPlaces parameter.
2D Vector
import { v2Sum, Vector2 } from 'toolcool-math';
const sum1 = v2Sum([1, 2], [3, 4]);
const vector1: Vector2 = [3.12456, 4.56734];
const vector2: Vector2 = [5.12323, 6.001234];
const sum2 = v2Sum(vector1, vector2, 2);
3D Vector
import { v3Sum, Vector3 } from 'toolcool-math';
const sum1 = v3Sum([1, 2, 3], [3, 4, 4]);
const vector1: Vector3 = [3.2345, 4.0013234, 5.2523453];
const vector2: Vector3 = [6.111, 7.222, 8.333];
const sum2 = v3Sum(vector1, vector2, 2);
General Case
import { vSum, Vector } from 'toolcool-math';
const v1: Vector = [1, 2, 3, 4];
const v2: Vector = [5, 6, 7, 8];
const sum = vSum(v1, v2);
Vectors Subtraction
The following functions are used to add vectors: v2Sub for a 2D vector, v3Sub for a 3D vector, and vSub for the general case. Each function receives an optional decimalPlaces parameter.
2D Vector
import { v2Sub, Vector2 } from 'toolcool-math';
const sub1 = v2Sub([1, 2], [3, 4]);
const vector1: Vector2 = [-1.125324, -2.23453245];
const vector2: Vector2 = [3.2345, 4.3574365];
const sub2 = v2Sub(vector1, vector2, 2);
3D Vector
import { v3Sub, Vector3 } from 'toolcool-math';
const sub1 = v3Sub([1, 2, 3], [3, 4, 4]);
const vector1: Vector3 = [1.12754, 2.999345, 3.34653456];
const vector2: Vector3 = [7.352345, 8.35734, 9.2345];
const sub2 = v3Sub(vector1, vector2, 2);
General Case
import { vSub, Vector } from 'toolcool-math';
const v1: Vector = [1, 2, 3, 4];
const v2: Vector = [5, 6, 7, 8];
const sum = vSub(v1, v2);
Multiply vector by scalar
The following functions are used to multiply a vector by a scalar: v2MulScalar for a 2D vector, v3MulScalar for a 3D vector, and vMulScalar for the general case. Each function receives an optional decimalPlaces parameter.
2D Vector
import { v2MulScalar } from 'toolcool-math';
const res = v2MulScalar([1, 2], 2);
const res = v2MulScalar([1, 2], 0.5);
const res = v2MulScalar([1, 2], Math.PI);
const res = v2MulScalar([1, 2], Math.PI, 2);
3D Vector
import { v3MulScalar } from 'toolcool-math';
const res = v3MulScalar([1, 2, 3], 2);
const res = v3MulScalar([1, 2, 3], 0.5);
const res = v3MulScalar([1, 2, 3], Math.PI);
const res = v3MulScalar([1, 2, 3], Math.PI, 2);
General Case
import { vMulScalar } from 'toolcool-math';
const res = v3MulScalar([1, 2, 3, 4], 2);
Divide vector by scalar
The following functions are used to divide a vector by a scalar: v2DivideScalar for a 2D vector, v3DivideScalar for a 3D vector, and vDivideScalar for the general case. Each function receives an optional decimalPlaces parameter.
2D Vector
import { v2DivideScalar } from 'toolcool-math';
const res = v2DivideScalar([1, 2], 2);
const res = v2DivideScalar([1, 2], 0.5);
const res = v2DivideScalar([1, 2], Math.PI);
const res = v2DivideScalar([1, 2], Math.PI, 2);
3D Vector
import { v3DivideScalar } from 'toolcool-math';
const res = v3DivideScalar([1, 2, 3], 2);
const res = v3DivideScalar([1, 2, 3], 0.5);
const res = v3DivideScalar([1, 2, 3], Math.PI);
const res = v3DivideScalar([1, 2, 3], Math.PI, 2);
General Case
import { vDivideScalar } from 'toolcool-math';
const res = vDivideScalar([1, 2, 3, 4], 2);
Get Vector Length
Vector length can be found using the v2Length, v3Length, and vLength functions. Each function receives an optional decimalPlaces parameter.
import { v2Length, v3Length, vLength } from 'toolcool-math';
const len1 = v2Length([1, 2]);
const len2 = v2Length([1, 2], 2);
const len3 = v3Length([1, 2, 3]);
const len4 = v3Length([1, 2, 3], 2);
const len5 = vLength([1, 2, 3, 4]);
const len6 = vLength([1, 2, 3, 4], 2);
Set Vector Length
It's possible to update vector length using v2SetLength function. The function receives an optional decimalPlaces parameter.
import { v2SetLength } from 'toolcool-math';
const res1 = v2SetLength([1, 2], 10);
const res2 = v2SetLength([1, 2], 10, 2);
Normalize Vector
It's possible to normalize vectors using the v2Normalize, v3Normalize, and vNormalize functions. Each function receives an optional decimalPlaces parameter.
import { v2Normalize, v3Normalize, vNormalize } from 'toolcool-math';
const res1 = v2Normalize([10, 20]);
const res2 = v2Normalize([10, 20], 2);
const res3 = v3Normalize([10, 20, 30]);
const res4 = v3Normalize([10, 20, 30], 2);
const res5 = vNormalize([10, 20, 30, 40]);
const res6 = vNormalize([10, 20, 30, 40], 2);
Vectors Dot Product
It's possible to calculate vector dot product using the v2DotProduct, v3DotProduct, and vDotProduct functions. Each function receives an optional decimalPlaces parameter.
import { v2DotProduct, v3DotProduct, vDotProduct } from 'toolcool-math';
const res1 = v2DotProduct([1, 2], [3, 4]);
const res2 = v2DotProduct([1.1234, 2.35678], [3.1265, 4.91355], 2);
const res3 = v3DotProduct([1, 2, 3], [4, 5, 6]);
const res4 = v3DotProduct([1.73845, 2.88465, 3.000111], [4.1163, 5.5501, 6.120777], 2);
const res5 = vDotProduct([1, 2, 3, 4], [5, 6, 7, 8]);
const res6 = vDotProduct([1.123, 2.123, 3.123, 4.123], [5.123, 6.123, 7.123, 8.123], 1);
Vectors Cross Product
import { v3CrossProduct, Vector3 } from 'toolcool-math';
const v1: Vector3 = [1, 2, 3];
const v2: Vector3 = [4, 5, 6];
const res1 = v3CrossProduct(v1, v2);
const v3: Vector3 = [1.1143, 2.1205, 3.57294];
const v4: Vector3 = [4.8294, 5.0001111, 6.48634];
const res2 = v3CrossProduct(v3, v4, 2);
Get distance between 2 vectors
2D vectors
import { v2Distance, Vector2 } from 'toolcool-math';
const v1: Vector2 = [1, 2];
const v2: Vector2 = [4, 5];
const distance = v2Distance(v1, v2);
3D vectors
import { v3Distance, Vector2 } from 'toolcool-math';
const v1: Vector2 = [1, 2, 3];
const v2: Vector2 = [4, 5, 6];
const distance = v3Distance(v1, v2);
General case
import { vDistance, Vector } from 'toolcool-math';
const v1: Vector = [1, 2, 3];
const v2: Vector = [4, 5, 6];
const distance = vDistance(v1, v2);
Vector Initialization Helpers
There are helpers for creating v2, v3 and vN vectors with a default value. If no default value is specified, it will be zero.
import { v2, v3, v4, vN } from 'toolcool-math';
const v2 = v2();
const v2_10 = v2(10);
const v3 = v3();
const v3_10 = v3(10);
const v4 = v4();
const v4_10 = v4(10);
const v5 = vN(5);
const v5_10 = vN(5, 10);
Initialize vector using polar coordinates
import { Vector2 } from 'toolcool-math';
const distance = 10;
const angleRad = Math.PI/4;
const v2: Vector2 = v2FromPolarCoords(distance, angleRad);
Check if 2 vectors are equal
It's possible to perform a deep comparison of two vectors using the vEqual function:
import { vEqual } from 'toolcool-math';
const res1 = vEqual([1, 0], [1, 0]);
const res2 = vEqual([1, 0], [0, 1]);
const res3 = vEqual([0, 0, 0], [0, 0]);
Matrix
There are the following types of matrices:
Matrix2, Matrix3, and Matrix for the general case.
Matrix2
import { Matrix2 } from 'toolcool-math';
const m2: Matrix2 = [
[1, 2],
];
const m2: Matrix2 = [
[1, 2],
[3, 4],
];
const m2: Matrix2 = [
[1, 2],
[3, 4],
[5, 6],
];
Matrix3
import { Matrix3 } from 'toolcool-math';
const m3: Matrix3 = [
[1, 2, 3],
];
const m3: Matrix3 = [
[1, 2, 3],
[4, 5, 6],
];
const m3: Matrix3 = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
];
Matrix4
import { Matrix4 } from 'toolcool-math';
const m4: Matrix4 = [
[1, 2, 3, 4],
];
const m4: Matrix4 = [
[1, 2, 3, 4],
[5, 6, 7, 8],
];
const m4: Matrix4 = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
];
The generic Matrix type is used for all other cases:
import { Matrix } from 'toolcool-math';
const m: Matrix = [
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
];
Matrix Initialization Helpers
m2x2, m3x3, and mNxM
There are helpers for creating m2x2, m3x3, and mNxM matrices with a default value. If no default value is specified, it will be zero.
import { m2x2, m3x3, m4x4, mNxM } from 'toolcool-math';
const mat2x2 = m2x2();
const mat2x2_10 = m2x2(10);
const mat3x3 = m3x3();
const mat3x3_20 = m3x3(20);
const mat4x4_5 = m5x5(5);
const matNxM = mNxM(1, 5);
const matNxM = mNxM(2, 3, 1);
Identity Matrix
There are helpers for creating identity matrices: identity2, identity3, and identityN.
import { identity2, identity3, identity4, identityN } from 'toolcool-math';
const idt2 = identity2();
const idt3 = identity3();
const idt4 = identity4();
const idt5 = identityN(5);
Manipulation Helpers
Check if 2 matrices are equal
It's possible to perform a deep comparison of two matrices using the mEqual function:
import { mEqual } from 'toolcool-math';
const res1 = mEqual(
[
[0, 0],
[0, 0],
],
[
[0, 0],
[0, 0],
]);
const res2 = mEqual(
[
[1, 0],
[0, 0],
],
[
[0, 0],
[0, 1],
]);
Matrix Deep Copy
There are 3 function for matrices deep copy: m2DeepCopy for 2D matrices, m3DeepCopy for 3D matrices, and mDeepCopy for the general case:
import { Matrix2, m2DeepCopy } from 'toolcool-math';
const m2: Matrix2 = [
[3, 5],
[-7, 2],
];
const copyM2 = m2DeepCopy(m2);
import { Matrix3, m3DeepCopy } from 'toolcool-math';
const m2: Matrix3 = [
[3, 5, 1],
[-7, 2, 6],
];
const copyM3 = m2DeepCopy(m3);
import { Matrix, mDeepCopy } from 'toolcool-math';
const m: Matrix = [
[1, 0, 1, 2, 4],
[1, 7, 8, 6, 12],
];
const copy = mDeepCopy(m);
Append or prepend a row to a matrix
import { Matrix2, Vector2, m2AppendRow, m2PrependRow } from 'toolcool-math';
const m2: Matrix2 = [
[3, 5],
[-7, 2],
];
const v2: Vector2 = [3, 4];
const res1 = m2AppendRow(m2, v2);
const res2 = m2PrependRow(m2, v2);
import { Matrix3, Vector3, m3AppendRow, m3PrependRow } from 'toolcool-math';
const m3: Matrix3 = [
[1, 2, 3],
[4, 5, 6],
];
const v3: Vector3 = [7, 8, 9];
const res1 = m3AppendRow(m3, v3);
const res2 = m3PrependRow(m3, v3);
import { Matrix, Vector, mAppendRow, mPrependRow } from 'toolcool-math';
const m: Matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
];
const v: Vector = [9, 10, 11, 12];
const res1 = mAppendRow(m, v);
const res2 = mPrependRow(m, v);
Append or prepend a column to a matrix
import { Matrix, Vector, mAppendCol, mPrependCol } from 'toolcool-math';
const m: Matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
];
const v: Vector = [9, 10];
const res1 = mAppendCol(m, v);
const res2 = mPrependCol(m, v);
Remove row or column from matrix
Delete last row
import { mDelLastRow } from 'toolcool-math';
const res = mDelLastRow(
[
[3, 5],
[-7, 2],
]
);
Delete first row
import { mDelFirstRow } from 'toolcool-math';
const res = mDelFirstRow(
[
[3, 5],
[-7, 2],
]
);
Delete last column
import { mDelLastColumn } from 'toolcool-math';
const res = mDelLastColumn(
[
[3, 5],
[-7, 2],
]
);
Delete first column
import { mDelFirstColumn } from 'toolcool-math';
const res = mDelFirstColumn(
[
[3, 5],
[-7, 2],
]
);
Get column from matrix
import { Matrix, mGetFirstColumn, mGetLastColumn, mGetColumn } from 'toolcool-math';
const m: Matrix = [
[1, 0, 1, 1],
[1, 0, 1, 1],
[0, 0, 1, 1],
[0, 0, 1, -1],
];
const firstColumn = mGetFirstColumn(m);
const lastColumn = mGetLastColumn(m);
const col2 = mGetColumn(m, 2);
Matrix Sum
The following functions are used to add matrices: m2Sum for a 2D matrices, m3Sum for a 3D matrices, and mSum for the general case. Each function receives an optional decimalPlaces parameter.
2D Matrix
import { m2Sum, Matrix2 } from 'toolcool-math';
const matrix1: Matrix2 = [
[1, 2],
[3, 4],
];
const matrix2: Matrix2 = [
[5, 6],
[7, 8],
];
const sum = m2Sum(matrix1, matrix2);
3D Matrix
import { m3Sum, Matrix3 } from 'toolcool-math';
const matrix1: Matrix3 = [
[1, 2, 10],
[3, 4, 20],
];
const matrix2: Matrix3 = [
[5, 6, 30],
[7, 8, 40],
];
const sum = m3Sum(matrix1, matrix2);
General Case
import { mSum, Matrix } from 'toolcool-math';
const matrix1: Matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
];
const matrix2: Matrix = [
[9, 10, 11, 12],
[13, 14, 15, 16],
];
const sum = mSum(matrix1, matrix2);
Matrix Subtraction
The following functions are used to subtract matrices: m2Sub for a 2D matrices, m3Sub for a 3D matrices, and mSub for the general case. Each function receives an optional decimalPlaces parameter.
2D Matrix
import { m2Sub, Matrix2 } from 'toolcool-math';
const matrix1: Matrix2 = [
[1, 2],
[3, 4],
];
const matrix2: Matrix2 = [
[5, 6],
[7, 8],
];
const sub = m2Sub(matrix1, matrix2);
3D Matrix
import { m2Sub, Matrix3 } from 'toolcool-math';
const matrix1: Matrix3 = [
[1, 2, 10],
[3, 4, 20],
];
const matrix2: Matrix3 = [
[5, 6, 30],
[7, 8, 40],
];
const sub = m2Sub(matrix1, matrix2);
General Case
import { mSub, Matrix } from 'toolcool-math';
const matrix1: Matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
];
const matrix2: Matrix = [
[9, 10, 11, 12],
[13, 14, 15, 16],
];
const sum = mSub(matrix1, matrix2);
Multiply matrix by scalar
You can multiply a matrix by a scalar using the m2MulScalar, m3MulScalar, or mMulScalar functions. Each function receives an optional decimalPlaces parameter.
2D Matrix
import { m2MulScalar, Matrix2 } from 'toolcool-math';
const m2: Matrix2 = [
[1, 2],
[3, 4],
];
const res = m2MulScalar(m2, 5);
import { m2MulScalar, Matrix2 } from 'toolcool-math';
const m2: Matrix2 = [
[1.12345, 12.66746776],
[15.74432, -12.345345],
];
const res = m2MulScalar(m2, 10, 2);
3D Matrix
import { m3MulScalar, Matrix3 } from 'toolcool-math';
const m3: Matrix3 = [
[1, 2, 3],
[4, 5, 6],
];
const res = m3MulScalar(m3, 2);
import { m3MulScalar, Matrix3 } from 'toolcool-math';
const m3: Matrix3 = [
[1, 2, 3],
[4, 5, 6],
];
const res = m3MulScalar(m3, 1.5123123, 1);
Divide matrix by scalar
You can multiply a matrix by a scalar using the m2DivideScalar, m3DivideScalar, or mDivideScalar functions. Each function receives an optional decimalPlaces parameter.
2D Matrix
import { m2DivideScalar, Matrix2 } from 'toolcool-math';
const m2: Matrix2 = [
[1, 2],
[3, 4],
];
const res = m2DivideScalar(m2, 5);
import { m2DivideScalar, Matrix2 } from 'toolcool-math';
const m2: Matrix2 = [
[1.12345, 12.66746776],
[15.74432, -12.345345],
];
const res = m2DivideScalar(m2, 10, 2);
3D Matrix
import { m3DivideScalar, Matrix3 } from 'toolcool-math';
const m3: Matrix3 = [
[1, 2, 3],
[4, 5, 6],
];
const res = m3DivideScalar(m3, 2);
import { m3DivideScalar, Matrix3 } from 'toolcool-math';
const m3: Matrix3 = [
[1, 2, 3],
[4, 5, 6],
];
const res = m3DivideScalar(m3, 1.5123123, 1);
General Case
import { mDivideScalar, Matrix } from 'toolcool-math';
const matrix: Matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
];
const res = mDivideScalar(matrix, 5);
Matrix Transposition
You can transpose a matrix using the m2Transpose, m3Transpose, or mTranspose functions.
2D Matrix
import { m2Transpose, Matrix2 } from 'toolcool-math';
const m2: Matrix2 = [
[-1, 5],
[Math.PI, 3],
];
const res = m2Transpose(m2);
3D Matrix
import { m3Transpose, Matrix3 } from 'toolcool-math';
const m3: Matrix3 = [
[1, 3, 7],
[-2, 0, 5],
];
const res = m3Transpose(m3);
General Case
import { mTranspose, Matrix } from 'toolcool-math';
const matrix: Matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
];
const res = mTranspose(matrix);
Matrix Multiplication
You can multiply matrices using the mMul function. The function receives an optional decimalPlaces parameter.
import { mMul, Matrix3, Matrix2 } from 'toolcool-math';
const matrix1: Matrix3 = [
[0, 3, 5],
[5, 5, 2],
];
const matrix2: Matrix2 = [
[3, 4],
[3, -2],
[4, -2],
];
const res = mMul(matrix1, matrix2);
import { mMul, Matrix2 } from 'toolcool-math';
const matrix1: Matrix2 = [
[2.092345, -2.2345234],
[5.56745, 3.235479],
];
const matrix2: Matrix2 = [
[-1.46874567, 4.23453245],
[7.234505, -6.93245],
];
const res = mMul(matrix1, matrix2, 2);
Multiply matrix by vector
You can multiply matrix by vector using the mMulVector function. The function receives an optional decimalPlaces parameter.
import { mMulVector, Matrix3 } from 'toolcool-math';
const matrix: Matrix3 = [
[0, 3, 5],
[5, 5, 2],
];
const vector: Vector3 = [3, 4, 3];
const res = mMulVector(matrix, vector);
Reset matrix with a default value
It is possible to reset all matrix values with some default value. If no default value is specified, it will be zero.
2D Matrix
import { Matrix2, m2Reset } from 'toolcool-math';
const m2: Matrix2 = [
[1, 2],
[3, 4],
];
const res = m2Reset(m2);
import { Matrix2, m2Reset } from 'toolcool-math';
const m2: Matrix2 = [
[1, 2],
[3, 4],
];
const res = m2Reset(m2, 10);
3D Matrix
import { Matrix3, m3Reset } from 'toolcool-math';
const m3: Matrix3 = [
[1, 2, 3],
[4, 5, 6],
];
const res = m3Reset(m3);
import { Matrix3, m3Reset } from 'toolcool-math';
const m3: Matrix3 = [
[1, 2, 3],
[4, 5, 6],
];
const res = m3Reset(m3, 1.5);
General Case
import { Matrix, m3Reset } from 'toolcool-math';
const m: Matrix = [
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
];
const res = m3Reset(m);
import { Matrix, m3Reset } from 'toolcool-math';
const m: Matrix = [
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
];
const res = m3Reset(m, 50);
Transformation Matrices
Translation Matrix
It's possible to get a translation matrix using the functions below. Each function supports an optional decimalPlaces parameter.
Translation in non-homogeneous coordinates
import { m2Translation, m3Translation, Matrix2, Matrix3 } from 'toolcool-math';
const mat1: Matrix2 = m2Translation([10, 20]);
const mat2: Matrix3 = m3Translation([10, 20, 30]);
Translation in homogeneous coordinates
import { m2TranslationH, m3TranslationH, Matrix3, Matrix4 } from 'toolcool-math';
const mat1: Matrix3 = m2TranslationH([10, 20, 1]);
const mat2: Matrix4 = m3TranslationH([10, 20, 30, 1]);
Rotation Matrix
2D rotation matrix
It's possible to get a 2D rotation matrix for a given angle in radians as follows:
import { m2Rotation, Matrix2, Matrix3 } from 'toolcool-math';
let angle = Math.PI/2;
let isClockwise = true;
let decimalPlaces = 3;
const mat1: Matrix2 = m2Rotation(angle, isClockwise, decimalPlaces);
let angle = Math.PI/2;
let isClockwise = true;
let decimalPlaces = 3;
let mat2: Matrix3 = m2RotationH(angle, isClockwise, decimalPlaces);
It is also possible to get the actual rotated vector using the v2Rotate and v2RotateH functions. Each function supports an optional decimalPlaces parameter.
import { Vector2, Vector3, v2Rotate, v2RotateH } from 'toolcool-math';
let angle = Math.PI/2;
let vector: Vector2 = [10, 20];
let isClockwise = true;
let decimalPlaces = 3;
const rotatedVector1: Vector2 = v2Rotate(angle, vector, isClockwise, decimalPlaces);
let angle = Math.PI/2;
let vector: Vector3 = [10, 20, 1];
let isClockwise = true;
let decimalPlaces = 3;
const rotatedVector2: Vector3 = v2RotateH(angle, vector, isClockwise, decimalPlaces);
3D rotation matrices
It's possible to get the following 3D rotation matrices:
non-homogeneous coordinates
import { m3RotationX, m3RotationY, m3RotationZ, Matrix3 } from 'toolcool-math';
let angle = Math.PI/2;
let isClockwise = true;
let decimalPlaces = 3;
const rmat3x: Matrix3 = m3RotationX(angle, isClockwise, decimalPlaces);
let angle = Math.PI/2;
let isClockwise = true;
let decimalPlaces = 3;
const rmat3y: Matrix3 = m3RotationY(angle, isClockwise, decimalPlaces);
let angle = Math.PI/2;
let isClockwise = true;
let decimalPlaces = 3;
const rmat3z: Matrix3 = m3RotationZ(angle, isClockwise, decimalPlaces);
homogeneous coordinates
import { m3RotationXH, m3RotationYH, m3RotationZH, Matrix4 } from 'toolcool-math';
let angle = Math.PI/2;
let isClockwise = true;
let decimalPlaces = 3;
const rmat3x: Matrix4 = m3RotationXH(angle, isClockwise, decimalPlaces);
let angle = Math.PI/2;
let isClockwise = true;
let decimalPlaces = 3;
const rmat3y: Matrix4 = m3RotationYH(angle, isClockwise, decimalPlaces);
let angle = Math.PI/2;
let isClockwise = true;
let decimalPlaces = 3;
const rmat3z: Matrix4 = m3RotationZH(angle, isClockwise, decimalPlaces);
It is also possible to get the actual rotated vector using the following functions:
import { Vector3, v3RotateX, v3RotateY, v3RotateZ } from 'toolcool-math';
let angle = Math.PI/2;
let vector: Vector3 = [10, 20, 30];
let isClockwise = true;
let decimalPlaces = 3;
const rotatedVector1: Vector3 = v3RotateX(angle, vector, isClockwise, decimalPlaces);
let angle = Math.PI/2;
let vector: Vector3 = [10, 20, 30];
let isClockwise = true;
let decimalPlaces = 3;
const rotatedVector2: Vector3 = v3RotateY(angle, vector, isClockwise, decimalPlaces);
let angle = Math.PI/2;
let vector: Vector3 = [10, 20, 30];
let isClockwise = true;
let decimalPlaces = 3;
const rotatedVector3: Vector3 = v3RotateZ(angle, vector, isClockwise, decimalPlaces);
Rotate around the point
It's possible to rotate a point [x, y] (in homogeneous coordinates) around the given origin as follows:
import { Vector3, m2RotationAroundPointH } from 'toolcool-math';
const angle = Math.PI/4;
const transformOrigin = [100, 100, 1];
const point: Vector3 = [150, 150, 1];
const isClockwise = true;
const decimalPlaces = 2;
const pos: Vector3 = m2RotateAroundPointH(
angle,
transformOrigin,
point,
isClockwise,
decimalPlaces
);
const mat3: Matrix3 = m2RotationAroundPointH(
angle,
transformOrigin,
isClockwise,
decimalPlaces
);
Circle Movement Example
Scale/Stretch Matrix
2D scale matrix
It's possible to get a 2D scale matrix for a given scale vector as follows:
import { m2Scale, m2ScaleX, m2ScaleH, m2ScaleXH, m2ScaleYH, Matrix2, Matrix3 } from 'toolcool-math';
const mat1: Matrix2 = m2Scale([2, 4]);
const mat1: Matrix3 = m2ScaleH([2, 4, 1]);
const mat2: Matrix2 = m2ScaleX(2);
const mat2: Matrix3 = m2ScaleXH(2);
const mat3: Matrix2 = m2ScaleY(2);
const mat3: Matrix3 = m2ScaleYH(2);
It is also possible to get the actual scaled vector using the v2Scale function:
import { Vector2, v2Scale } from 'toolcool-math';
const scaledVector: Vector2 = v2Scale([2, 4], [10, 20]);
3D scale matrix
It's possible to get a 3D scale matrix for a given scale vector as follows:
import { m3Scale, m3ScaleH, Matrix3, Matrix4 } from 'toolcool-math';
const smat3: Matrix3 = m3Scale([2, 4, 6]);
const smat3: Matrix4 = m3ScaleH([2, 4, 6, 1]);
It is also possible to get the actual scaled vector using the v3Scale function:
import { Vector3, v3Scale } from 'toolcool-math';
const scaledVector: Vector3 = v3Scale([2, 4, 6], [10, 20, 30]);
Stretch in different directions:
import { m3ScaleX, m3ScaleY, m3ScaleZ, m3ScaleXH, Matrix3, Matrix4 } from 'toolcool-math';
const mat: Matrix3 = m3ScaleX(2);
const mat: Matrix4 = m3ScaleXH(2);
const mat: Matrix3 = m3ScaleY(2);
const mat: Matrix4 = m3ScaleYH(2);
const mat: Matrix3 = m3ScaleZ(2);
const mat: Matrix4 = m3ScaleZH(2);
Scale about an arbitrary pivot point P
It's possible to scale a point [x, y] (in homogeneous coordinates) around the given pivot point as follows:
import { Vector3, m2ScaleAtPointH, m2ScaleAtPointHMatrix } from 'toolcool-math';
const scaleVector: Vector3 = [2, 4, 1];
const transformOrigin = [100, 100, 1];
const point: Vector3 = [150, 150, 1];
const decimalPlaces = 2;
const res: Vector3 = m2ScaleAtPointH(
scaleVector,
transformOrigin,
point,
decimalPlaces
);
const mat3: Matrix3 = m2ScaleAtPointHMatrix(
scaleVector,
transformOrigin,
decimalPlaces
);
Reflection Matrix
2D reflection matrix
It's possible to get a 2D reflection matrices as follows:
import {
m2ReflectionOrigin, m2ReflectionOriginH,
m2ReflectionX, m2ReflectionXH,
m2ReflectionY, m2ReflectionYH,
m2ReflectionYX, m2ReflectionYmX,
Matrix2
} from 'toolcool-math';
const mat0: Matrix2 = m2ReflectionOrigin();
const mat0: Matrix3 = m2ReflectionOriginH();
const mat1: Matrix2 = m2ReflectionX();
const mat1: Matrix3 = m2ReflectionXH();
const mat2: Matrix2 = m2ReflectionY();
const mat2: Matrix3 = m2ReflectionYH();
const mat3: Matrix2 = m2ReflectionYX();
const mat3: Matrix2 = m2ReflectionYmX();
3D reflection matrix
It's possible to get a 3D reflection matrices as follows:
import {
m3ReflectionOrigin, m3ReflectionOriginH,
m3ReflectionYZ, m3ReflectionYZH,
m3ReflectionXZ, m3ReflectionXZH,
m3ReflectionXY, m3ReflectionXYH,
Matrix3, Matrix4 } from 'toolcool-math';
const mat0: Matrix3 = m3ReflectionOrigin();
const mat0: Matrix4 = m3ReflectionOriginH();
const mat2: Matrix3 = m3ReflectionYZ();
const mat2: Matrix4 = m3ReflectionYZH();
const mat2: Matrix3 = m3ReflectionXZ();
const mat2: Matrix4 = m3ReflectionXZH();
const mat2: Matrix3 = m3ReflectionXY();
const mat2: Matrix4 = m3ReflectionXYH();
Shearing Matrix
2D shearing matrix
import { m2ShearingX, m2ShearingY, Matrix2 } from 'toolcool-math';
const factor = 5;
const mat1: Matrix2 = m2ShearingX(factor);
const factor = 5;
const mat2: Matrix2 = m2ShearingY(factor);
Matrix to CSS transform
The functions below help to convert the matrix to the following CSS functions: matrix() and matrix3d().
import { Matrix3, m2hToCSS } from 'toolcool-math';
const mat: Matrix3 = [
[1, 2, 0],
[3, 4, 0],
[0, 0, 1],
];
const str1 = m2hToCSS(mat);
It can be used as:
.box{
transform: matrix(1, 3, 2, 4, 0, 4);
}
matrix3d() representation:
import { Matrix3, m2hToCSS3d } from 'toolcool-math';
const mat: Matrix3 = [
[1, 2, 0],
[3, 4, 0],
[0, 0, 1],
];
const str1 = m2hToCSS3d(mat);
Non-homogeneous coordinates version:
import { Matrix2, m2ToCSS } from 'toolcool-math';
const mat: Matrix2 = [
[1, 2],
[3, 4],
];
const str1 = m2ToCSS(mat);
3D matrix in homogeneous coordinates:
import { Matrix4, m3hToCSS3d } from 'toolcool-math';
const mat: Matrix4 = [
[1, 0, 0, 10],
[0, 1, 0, 20],
[0, 0, 1, 30],
[0, 0, 0, 1],
];
const str1 = m3hToCSS3d(mat);
Matrix to CSS transform example (rotation)
Matrix Determinant
The determinant can be calculated for any square matrix using the m2Determinant function for a 2x2 matrix, using the m3Determinant function for a 3x3 matrix, or using mDeterminant for the general case.
Calculating the determinant for a 2x2 matrix:
import { Matrix2, m2Determinant } from 'toolcool-math';
const m2x2: Matrix2 = [
[5, 3],
[-1, 4],
];
const d = m2Determinant(m2x2);
Calculating the determinant for a 3x3 matrix:
import { Matrix3, m3Determinant } from 'toolcool-math';
const m3x3: Matrix3 = [
[4, -1, 1],
[4, 5, 3],
[-2, 0, 0],
];
const d = m3Determinant(m3x3);
Calculating the determinant for a 4x4 matrix or above:
import { Matrix, mDeterminant } from 'toolcool-math';
const m4x4: Matrix = [
[4, 3, 2, 2],
[0, 1, -3, 3],
[0, -1, 3, 3],
[0, 3, 1, 1]
];
const d = mDeterminant(m4x4);
Inverse Matrix
To inverse matrices, you can use the m2Inverse, m3Inverse, or mInverse functions. Each function supports an optional decimalPlaces parameter. If matrix is not invertible, the functions return null.
2x2 matrix
import { Matrix2, m2Inverse } from 'toolcool-math';
const m2x2: Matrix2 = [
[3, 5],
[-7, 2],
];
const inverted: Matrix2|null = m2Inverse(m2x2, 3);
3x3 matrix
import { Matrix3, m3Inverse } from 'toolcool-math';
const m3x3: Matrix3 = [
[-1, -2, 2],
[2, 1, 1],
[3, 4, 5]
];
const inverted: Matrix3|null = m3Inverse(m3x3, 2);
3x3 matrix or above
import { Matrix, mInverse } from 'toolcool-math';
const m4x4: Matrix = [
[1, 1, 1, -1],
[1, 1, -1, 1],
[1, -1, 1, 1],
[-1, 1, 1, 1],
];
const inverted: Matrix|null = mInverse(m4x4);
Check if matrix is singular
import { Matrix, isSingularMatrix } from 'toolcool-math';
const m: Matrix = [
[3, 5],
[-7, 2],
];
const isSingular = isSingularMatrix(m);
import { Matrix, isSingularMatrix } from 'toolcool-math';
const m: Matrix = [
[2, 4, 6],
[2, 0, 2],
[6, 8, 14],
];
const isSingular = isSingularMatrix(m);
Adjugate Matrix
To adjugate matrices, you can use the m2Adjugate, m3Adjugate, or mAdjugate functions. Each function supports an optional decimalPlaces parameter. If matrix can't be adjugated, the functions return null.
2x2 matrix
import { Matrix2, m2Adjugate } from 'toolcool-math';
const m2x2: Matrix2 = [
[3, 5],
[-7, 2],
];
const adj: Matrix2 | null = m2Adjugate(m2x2);
3x3 matrix
import { Matrix3, m3Adjugate } from 'toolcool-math';
const m3x3: Matrix3 = [
[3, 5, 1],
[-7, 2, 5],
[1, 2, 3],
];
const adj: Matrix3 | null = m3Adjugate(m3x3);
4x4 matrix or above
import { Matrix, mAdjugate } from 'toolcool-math';
const m4x4: Matrix = [
[1, 1, 1, -1],
[1, 1, -1, 1],
[1, -1, 1, 1],
[-1, 1, 1, 1],
];
const adj: Matrix | null = mAdjugate(m4x4);
Get Matrix Minor
import { Matrix, mMinor } from 'toolcool-math';
const m: Matrix = [
[4, 3, 2, 2],
[0, 1, -3, 3],
[0, -1, 3, 3],
[0, 3, 1, 1],
];
const minor: Matrix = mMinor(m, 0, 0);
Angles
Get vector angle
The getV2Angle function returns the angle in radians between the positive x-axis and the ray from (0, 0) to the vector (x, y). It supports an optional decimalPlaces parameter. Each function returns a result in the range [0, Math.PI].
import { getV2Angle } from 'toolcool-math';
const angle1 = getV2Angle([10, 20]);
const angle2 = getV2Angle([10, 20], 2);
Set vector angle
If a 2D vector is given, change it to have the new angle (in radians). This function supports an optional decimalPlaces parameter.
import { setV2Angle } from 'toolcool-math';
const updatedVector1 = setV2Angle([10, 20], 1.22);
const updatedVector2 = setV2Angle([10, 20], 1.22, 2);
Get angle between two vectors
The following functions can be used to find the angle between two vectors. Each function returns a result in the range [0, Math.PI].
2D vectors:
import { getV2AngleBetween, Vector2 } from 'toolcool-math';
const vector1: Vector2 = [10, 20];
const vector2: Vector2 = [100, 150];
const decimalPlaces = 2;
const angle = getV2AngleBetween(vector1, vector2, decimalPlaces);
3D vectors:
import { getV3AngleBetween, Vector3 } from 'toolcool-math';
const vector1: Vector3 = [10, 20, 1];
const vector2: Vector3 = [100, 150, 1];
const decimalPlaces = 2;
const angle = getV3AngleBetween(vector1, vector2, decimalPlaces);
General case:
import { getVNAngleBetween, Vector } from 'toolcool-math';
const vector1: Vector = [10, 20, 1];
const vector2: Vector = [100, 150, 1];
const decimalPlaces = 2;
const angle = getVNAngleBetween(vector1, vector2, decimalPlaces);
Degrees to radians
import { degreesToRadians } from 'toolcool-math';
const res1 = degreesToRadians(90);
const res2 = degreesToRadians(90, 2);
Radians to degrees
import { radiansToDegrees } from 'toolcool-math';
const res = radiansToDegrees(1.5708);
const res = radiansToDegrees(1.5708, 0);
const res = radiansToDegrees(3.14159, 3);
const res = radiansToDegrees(4.71239, 3);
Format
Set Decimal Places
This helper allows to format a number to show a selected number of decimal places.
import { setDecimalPlaces } from 'toolcool-math';
const res = setDecimalPlaces(1.2345, 2);
const res = setDecimalPlaces(1.2399, 2);
const res = setDecimalPlaces(1.2399, 0);
The result of this function is a number (not a string), so sometimes fewer decimal places will be displayed after rounding:
const res = setDecimalPlaces(1.239999, 4);
Convert
Convert string to number
This function converts a numeric string to a number. If the string is not a number, it returns the provided default value.
import { stringToNumber } from 'toolcool-math';
const res = stringToNumber('10.1234', 10);
const res = stringToNumber(undefined, 10);
const res = stringToNumber(null, 10);
const res = stringToNumber('aaa', 10);
Random
Get random number in range
This function returns a random number in the range [min, max]. It supports an optional decimalPlaces parameter.
import { getRandom } from 'toolcool-math';
const res1 = getRandom(10, 100);
const res2 = getRandom(10, 100, 2);
Get random integer
This function returns a random integer number in the range [min, max].
import { getRandomInt } from 'toolcool-math';
const res = getRandomInt(0, 100);
Get random boolean value
import { getRandomBoolean } from 'toolcool-math';
const res = getRandomBoolean();
Get random item from array
import { getRandomItemFromArray } from 'toolcool-math';
const item1 = getRandomItemFromArray([1,2,3,4,5]);
const item2 = getRandomItemFromArray(['a', 'b', 'c']);
const item3 = getRandomItemFromArray([{ test: 1 }, { test: 2 }, { test: 3 }]);
Random ID or GUID
import { guid, newId } from 'toolcool-math';
const res1 = newId();
const res2 = guid();
Bézier Curve
Get a point on a quadratic Bézier curve
Get a point on a quadratic Bézier curve as a function of time, where t is in the range [0, 1].
2D Vector
import { v2QuadraticBezierCurve } from 'toolcool-math';
const v2 = v2QuadraticBezierCurve(
0.5,
[0, 100],
[50, 0],
[100, 100]
);
const v2 = v2QuadraticBezierCurve(
0,
[0, 100],
[50, 0],
[100, 100]
);
const v2 = v2QuadraticBezierCurve(
1,
[0, 100],
[50, 0],
[100, 100]
);
3D Vector
import { v3QuadraticBezierCurve } from 'toolcool-math';
const v3 = v3QuadraticBezierCurve(
0.5,
[0, 100, 0],
[50, 0, 0],
[100, 100, 0]
);
const v3 = v3QuadraticBezierCurve(
0,
[0, 100, 0],
[50, 0, 0],
[100, 100, 0]
);
const v3 = v3QuadraticBezierCurve(
1,
[0, 100, 0],
[50, 0, 0],
[100, 100, 0]
);
Get a point on a cubic Bézier curve
Get a point on a cubic Bézier curve as a function of time, where t is in the range [0, 1].
2D Vector
import { v2CubicBezierCurve } from 'toolcool-math';
const v2 = v2CubicBezierCurve(
0.5,
[0, 100],
[0, 0],
[100, 0],
[100, 100]
);
const v2 = v2CubicBezierCurve(
0,
[0, 100],
[0, 0],
[100, 0],
[100, 100]
);
const v2 = v2CubicBezierCurve(
1,
[0, 100],
[0, 0],
[100, 0],
[100, 100]
);
3D Vector
import { v3CubicBezierCurve } from 'toolcool-math';
const v3 = v3CubicBezierCurve(
0.5,
[0, 100, 0],
[0, 0, 0],
[100, 0, 0],
[100, 100, 0]
);
const v3 = v3CubicBezierCurve(
0,
[0, 100, 0],
[0, 0, 0],
[100, 0, 0],
[100, 100, 0]
);
const v3 = v3CubicBezierCurve(
1,
[0, 100, 0],
[0, 0, 0],
[100, 0, 0],
[100, 100, 0]
);
Equations
System of linear equations
System of 2 linear equations
Using the equationSystem2 function, you can solve a system of 2 linear equations. It receives 2 vectors of equation parameters and an optional decimalPlaces parameter.
If the system of equations has no solution, then null is returned.
For example:
import { equationSystem2, Vector2, Vector3 } from 'toolcool-math';
const equation1: Vector3 = [3, 2, 7];
const equation2: Vector3 = [-6, 6, 6];
const result: Vector2|null = equationSystem2(equation1, equation2);
System of 3 linear equations
Using the equationSystem3 function, you can solve a system of 3 linear equations. It receives 3 vectors of equation parameters and an optional decimalPlaces parameter.
If the system of equations has no solution, then null is returned.
For example:
import { equationSystem3, Vector3, Vector } from 'toolcool-math';
const equation1: Vector = [2, 1, 2, -2];
const equation2: Vector = [-2, 2, -1, -5];
const equation3: Vector = [4, 1, 2, 0];
const result: Vector3|null = equationSystem3(equation1, equation2, equation3);
System of N linear equations
Using the equationSystemN function, you can solve a system of N linear equations. It receives a matrix of equation parameters, and an optional decimalPlaces parameter.
If the system of equations has no solution, then null is returned.
For example:
import { equationSystem, Vector } from 'toolcool-math';
const parameters: Matrix = [
[0, 1, 1, -2, -3],
[1, 2, -1, 0, 2],
[2, 4, 1, -3, -2],
[1, -4, -7, -1, -19],
];
const result: Vector|null = equationSystemN(parameters, 2);
Path Movement
Circle Movement
import { circleMovement, Vector2 } from 'toolcool-math';
const center: Vector2 = [100, 100];
const angle = Math.PI/2;
const radius = 250;
const newPosition: Vector2 = circleMovement(center, angle, radius);
Example
Circle movement after mouse
import { circleMovementAfterMouse, Vector2 } from 'toolcool-math';
const mouse = [evt.clientX, evt.clientY];
const center: Vector2 = [100, 100];
const radius = 250;
const position: Vector2 = circleMovementAfterMouse(mouse, center, radius);
Example
Ellipse Movement
import { ellipseMovement, Vector2 } from 'toolcool-math';
const center: Vector2 = [100, 100];
const angle = Math.PI/2;
const radius1 = 350;
const radius2 = 150;
const newPosition: Vector2 = ellipseMovement(center, angle, radius1, radius2);
Example
Sine Wave Movement
import { ellipseMovement, Vector2 } from 'toolcool-math';
const amplitude = 100;
const frequency = 0.003;
const phase = 0;
const x = 0;
const newPosition: Vector2 = ellipseMovement(x, amplitude, frequency, phase);
Example
Lissajous curve
import { lissajousCurve, Vector2, getRandom } from 'toolcool-math';
const m = 0;
const p = 0;
const t = 1;
const k = getRandom(0, Math.PI * 2);
const n = getRandom(0, Math.PI * 2);
const A = getRandom(0, 100);
const B = getRandom(0, 100);
const newPosition: Vector2 = TCMath.lissajousCurve(
A,
B,
t,
k,
n,
m,
p
);
Example
Color
The library contains several color helper functions. It works with the following color types:
import { HSLColor, RGBColor } from 'toolcool-math';
const hslColor: HSLColor = [0, 0, 0];
const rgbColor: RGBColor = [255, 255, 255];
Get random color
import {
HSLColor, RGBColor, getRandomHexColor,
getRandomRGBColor, getRandomHSLColor,
getRandomHSLColorWithHue, getRandomHSLColorWithSaturation,
getRandomHSLColorWithinRanges, getRandomGrayscaleHSLColor
} from 'toolcool-math';
const rgbColor: string = getRandomHexColor();
const rgbColor: RGBColor = getRandomRGBColor();
const hslColor1: HSLColor = getRandomHSLColor();
const hslColor2: HSLColor = getRandomHSLColorWithHue(300);
const hslColor2: HSLColor = getRandomHSLColorWithSaturation(50);
const hslColor3: HSLColor = getRandomHSLColorWithLightness(50);
const hslColor4: HSLColor = getRandomHSLColorWithinRanges(
10, 20,
0, 100,
30, 50,
);
const hslColor5: HSLColor = getRandomGrayscaleHSLColor();
Convert Colors
import { HSLColor, RGBColor, hslToRgb, rgbToHsl, hslToHex } from 'toolcool-math';
const decimalPlaces = 2;
const hslColor: HSLColor = rgbToHsl([255, 0, 0], decimalPlaces);
const rgbColor: RGBColor = hslToRgb([100, 100, 100], decimalPlaces);
const hex: string = hslToHex([10, 10, 10]);
Shift colors
import { HSLColor, getShiftedHue, getShiftedSaturation, getShiftedLightness } from 'toolcool-math';
const hslColor1: HSLColor = getShiftedHue([0, 0, 39], -10);
const hslColor2: HSLColor = getShiftedSaturation([0, 100, 39], 10);
const hslColor3: HSLColor = getShiftedLightness([0, 0, 39], 10);
Shapes
Square in circle
Get the side of a square inscribed in a circle of a given radius:
import { getSquareInCircleSide } from 'toolcool-math';
const circleRadius = 10;
const decimalPlaces = 2;
const squareSide = getSquareInCircleSide(10);
Other
Modulo
Calculate the modulo for positive or negative numbers.
import { mod } from 'toolcool-math';
const res1 = mod(-21, 4);
const res2 = mod(7, 3);
Convert range
Converting a number from the range [a,b] to the range [c,d].
import { convertRange } from 'toolcool-math';
const res = convertRange(0.5, 0, 1, 100, 200);
Check if two ranges overlap
import { doRangesOverlap } from 'toolcool-math';
const res1 = doRangesOverlap(0, 1, 100, 200);
const res2 = doRangesOverlap(0, 1, 0.5, 1.5);
Check if value can be converted to number
import { isNumber } from 'toolcool-math';
const res = isNumber('12');
const res = isNumber(12.5);
const res = isNumber('0');
const res = isNumber(0);
const res = isNumber('aaa');
const res = isNumber(null);
const res = isNumber(undefined);
const res = isNumber(Infinity);
License
MIT license
It can be used for free in any personal or commercial project :gift: