inverse-kinematics
Version:
Inverse kinematics for 2D and 3D applications
121 lines (120 loc) • 5.31 kB
JavaScript
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
to[j] = from[i];
return to;
};
import * as MathUtils from './MathUtils';
import * as QuaternionO from './QuaternionO';
var VECTOR_LENGTH = 3;
export var add = function (a, b) { return [a[0] + b[0], a[1] + b[1], a[2] + b[2]]; };
export var sum = function (vectors) {
var result = [0, 0, 0];
for (var vectorIndex = 0; vectorIndex < vectors.length; vectorIndex++) {
var vector = vectors[vectorIndex];
result[0] += vector[0];
result[1] += vector[1];
result[2] += vector[2];
}
return fromArray(result);
};
/**
* @returns a - b
*/
export var subtract = function (base, subtraction) { return [
base[0] - subtraction[0],
base[1] - subtraction[1],
base[2] - subtraction[2],
]; };
/**
* @returns element-wise multiplication of base and multiplier
*/
export var multiply = function (base, multiplier) { return [
base[0] * multiplier[0],
base[1] * multiplier[1],
base[2] * multiplier[2],
]; };
/**
* @returns a / b
*/
export var divide = function (base, divisor) { return [base[0] / divisor[0], base[1] / divisor[1], base[2] / divisor[2]]; };
export var scale = function (base, factor) { return [base[0] * factor, base[1] * factor, base[2] * factor]; };
export var sign = function (vector) { return [Math.sign(vector[0]), Math.sign(vector[1]), Math.sign(vector[2])]; };
export var normalise = function (vector) {
var length = euclideanLength(vector);
if (length === 0) {
return zero();
}
return scale(vector, 1 / length);
};
export var extractXY = function (vector) { return [vector[0], vector[1]]; };
export var extractXZ = function (vector) { return [vector[0], vector[2]]; };
export var extractYZ = function (vector) { return [vector[1], vector[2]]; };
export var sqrEuclideanLength = function (vector) { return manhattanLength(multiply(vector, vector)); };
export var manhattanLength = function (vector) { return vector[0] + vector[1] + vector[2]; };
export var dotProduct = function (a, b) {
var product = multiply(a, b);
return manhattanLength(product);
};
export var crossProduct = function (a, b) {
var ax = a[0], ay = a[1], az = a[2];
var bx = b[0], by = b[1], bz = b[2];
var x = ay * bz - az * by;
var y = az * bx - ax * bz;
var z = ax * by - ay * bx;
return [x, y, z];
};
export var euclideanLength = function (vector) { return Math.pow(sqrEuclideanLength(vector), 0.5); };
export var sqrEuclideanDistance = function (a, b) {
var distance = subtract(a, b);
return sqrEuclideanLength(distance);
};
export var euclideanDistance = function (a, b) {
var distance = subtract(a, b);
return euclideanLength(distance);
};
export var lerp = function (from, to, amount) { return [
MathUtils.lerp(from[0], to[0], amount),
MathUtils.lerp(from[1], to[1], amount),
MathUtils.lerp(from[2], to[2], amount),
]; };
export var lerpTheta = function (from, to, amount) { return [
MathUtils.lerpTheta(from[0], to[0], amount, Math.PI * 2),
MathUtils.lerpTheta(from[1], to[1], amount, Math.PI * 2),
MathUtils.lerpTheta(from[2], to[2], amount, Math.PI * 2),
]; };
export var up = function () { return [0, 1, 0]; };
export var down = function () { return [0, -1, 0]; };
export var right = function () { return [1, 0, 0]; };
export var left = function () { return [-1, 0, 0]; };
export var forwards = function () { return [0, 0, 1]; };
export var back = function () { return [0, 0, -1]; };
export var zero = function () { return [0, 0, 0]; };
export var copy = function (vector) { return [vector[0], vector[1], vector[2]]; };
export var flipX = function (vector) { return [-vector[0], vector[1], vector[2]]; };
export var flipY = function (vector) { return [vector[0], -vector[1], vector[2]]; };
export var flipZ = function (vector) { return [vector[0], vector[1], -vector[2]]; };
export var clamp = function (vector, min, max) { return [
MathUtils.clamp(vector[0], min[0], max[0]),
MathUtils.clamp(vector[1], min[1], max[1]),
MathUtils.clamp(vector[2], min[2], max[2]),
]; };
export var random = function () { return [Math.random(), Math.random(), Math.random()]; };
export var randomRange = function (min, max) { return add(scale(random(), max - min), [min, min, min]); };
export var fromArray = function (array) {
if (array.length !== VECTOR_LENGTH)
throw new Error("Cannot create V3 from " + array + ", length is " + array.length + ". Length should be " + VECTOR_LENGTH);
return array;
};
export var fromVector3 = function (vector) { return [vector.x, vector.y, vector.z]; };
export var rotate = function (vector, rotation) {
var conjugate = QuaternionO.conjugate(rotation);
var intermediate = QuaternionO.multiply(rotation, __spreadArray(__spreadArray([], vector), [0]));
var result = QuaternionO.multiply(intermediate, conjugate);
return [result[0], result[1], result[2]];
};
export var fromPolar = function (radius, angle) { return rotate([radius, 0, 0], angle); };
export var toPolar = function (vector) {
var radius = euclideanLength(vector);
var angle = QuaternionO.fromUnitDirectionVector(normalise(vector));
return [radius, angle];
};