cga-svd

A simple Javascript library for a number of Linear Algebra algorithms that rely on SVD

Usage no npm install needed!

<script type="module">
  import cgaSvd from 'https://cdn.skypack.dev/cga-svd';
</script>

README

CGA-SVD

npm

A simple Javascript library for a number of Linear Algebra algorithms that rely on SVD.

https://github.com/WilliamLiu-1997/cga-svd

Description

Procrustes: A multi-dimentioanl vector alignment algorithm (known as Constrained Orthogonal Procrustes Problem or Kabsch algorithm). Return a matrix(presenting the rotation (Scale and/or Reflection on demand)) and a vector(presenting the translation) that that align a set of n dimentional vectors to their corresponding targets.

VectorFitting: SVD vector fitting algorithm. Simulate a n dimentional plane that fits a set of n dimentional vectors. Return a n dimentional vectors('normal') presenting the direction of the plane and a n dimentional vectors('center') presenting its center position.

SVD: Singular Value Decomposition. Code from https://github.com/danilosalvati/svd-js

MatrixRotationAroundVectorPoint3D: Produce a rotation matrix and translation vector that performs a rotation around a rotation axis that pass a specific point (default is the origin) in space with a certain angle. (3D Space)

MatrixMultiply: Multiply two matrices.

Transform: Apply a Transform on a list of vectors.

Translate: Apply a Translation on a list of vectors.

MatrixInverse: Invert a matrix

MatrixTranspose: Transpose a matrix.

Determinant: Determinant of a squared matrix.

Install

npm install cga-svd

Usage

Procrustes(source, target, withTranslation, withScale, withReflection) => { transform, translation }

@param {Array} source: an list of n dimentional vectors, will be aligned to target
@param {Array} target: an list of n dimentional vectors
@param {Boolean} withTranslation: whether move to target positions, default is true
@param {Boolean} withScale: whether contain scaling, default is true
@param {Boolean} withReflection: whether contain reflection, default is false
@returns {Object}  An object containing:
        transform: a matrix presenting the rotation (Scale and/or Reflection on demand)
        translation: a vector presenting the translation
VectorFitting(vectors) => { normal, center }

@param {Array} vectors: A list of n dimentional vector
@returns {Object} An object containing:
        normal: n dimentional vectors presenting the direction of the n dimentional plane
        center: n dimentional vectors presenting the n dimentional plane center position
SVD(a, withu, withv, eps, tol) => { u, q, v}

See: https://github.com/danilosalvati/svd-js
MatrixRotationAroundVectorPoint3D(normal, angle, point) => { transform, translation }

@param {Array} normal The direction of rotation axis
@param {Number} angle The angle in radian to rotate
@param {Array} point A point on the rotation axis (optional, if not provided, assume the rotation axis will cross the origin)
@returns {Object}  An object containing:
        transform: a matrix presenting the rotation
        translation: a vector presenting the translation
MatrixMultiply(A, B) => results

Transform(Matrix, Vectors) => transformed vectors

Translate(Translation, Vectors) => translated vectors

MatrixInverse(A) => inverse of A

MatrixTranspose(A) => transpose of A

Determinant(A) => determinant of A

Examples

Procrustes

import { Procrustes } from 'cga-svd'

const source = [
    [5520256.7770074, 336354.37003699713, 3167002.52261562],
    [5520303.125007548, 336553.002625376, 3166783.194184834],
    [5520310.842973152, 336705.55202601955, 3167007.8452485506],
    [5520191.48555612, 336523.0133727255, 3166900.0472742445],
];

const target = [
    [5520446.76569624, 336367.3208137894, 3166268.4262278015],
    [5520524.811239348, 336385.0079539137, 3166133.338472933],
    [5520497.071423062, 336518.70720680256, 3166171.1038762117],
    [5520446.59762856, 336401.7774899081, 3166164.846668752],
];

const transform = Procrustes(source, target);

console.log(transform);

Output

{
    transform: [
        [0.48342920386037325, 0.0708119504810417, -0.1895852609563988],
        [0.06177151645240301, 0.4158938316122264, 0.3128534788522917],
        [0.19272047960195052, -0.3109319654584928, 0.3752876606631539],
    ],
    translation: [3428392.5996840945, -1135322.3833147655, 1018448.1011024625],
}

VectorFitting

import { VectorFitting } from 'cga-svd'

const vectors = [
    [5520446.76569624, 336367.3208137894, 3166268.4262278015],
    [5520524.811239348, 336385.0079539137, 3166133.338472933],
    [5520497.071423062, 336518.70720680256, 3166171.1038762117],
    [5520446.59762856, 336401.7774899081, 3166164.846668752],
    [5520256.7770074, 336354.37003699713, 3167002.52261562],
    [5520303.125007548, 336553.002625376, 3166783.194184834],
    [5520310.842973152, 336705.55202601955, 3167007.8452485506],
    [5520191.48555612, 336523.0133727255, 3166900.0472742445],
];

const plane = VectorFitting(vectors);

console.log(plane);

Output

{
    normal: [-0.9438538172977762, 0.15522796333103916, -0.29162347465955824],
    center: [5520372.184566429, 336476.0939406915, 3166553.9155711182],
}

Demo

A 3D web demo that uses these functions: https://cesium-tool.vercel.app/

Procrustes: Calibration -> Alignment(Better) (Click 4 points on grey model and click 4 points(should be the same position) on the other model, then click "Apply")

VectorFitting: Calibration -> Leveling (Click n point on a plane on grey model that is supposed to be horizontal, then click "Apply")