Skip to content

Commit

Permalink
feat(operator): algebraic multiply more operators
Browse files Browse the repository at this point in the history
  • Loading branch information
MrTelanie committed Aug 9, 2020
1 parent b2c70f3 commit 2316d99
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 15 deletions.
30 changes: 20 additions & 10 deletions src/operator.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ const CHECKED = Symbol('checked');
let inProgress = DEFAULT;
let inVector;
let elCount;
let last;
let current;
const allChecks = [0, 1, 2, 6, 24, 120, 720, 5760, 51840, 518400, 5702400, 68428800, 889574400, 12454041600, 186810624000];
const collect = [];


let resultCacheIndex = -1;
let handlingCache = false;
Expand All @@ -23,9 +24,10 @@ const resultCache = [];
function handleProgess(progess, alg, resVec) {
inProgress = progess;
resultCacheIndex = -1;
elCount = 0;
elCount = 1;

const res = alg(resVec);

if (typeof res !== 'number') {
throw new Error(`
your assigned progress did not not return a primitive!
Expand Down Expand Up @@ -130,22 +132,31 @@ export function operatorCalc(alg, result) {
if (inLen === CHECK_SUM) {
if (!alg[CHECKED]) {
const checkSum = handleProgess(CHECK_SUM, alg);
if (Math.abs(checkSum - 2) > Number.EPSILON) {

const sum = allChecks[elCount];
if (Math.abs(checkSum - sum) > Number.EPSILON) {
throw new Error(`
algebraic multiplication works only in simple calls
algebraic multiplication works only in calls with *
calc(() => v * m);
calc(() => m * v);
calc(() => m * m);
calc(() => m * m * v);
`);
}
alg[CHECKED] = true;
}
if (!last.multiply) {
throw new Error(`cannot find method multiply() on ${last}`);

let last = collect[0];
for (let i = 1; i < elCount - 1; i += 1) {
const current = collect[i];
if (!last.multiply) {
throw new Error(`cannot find method multiply() on ${last}`);
}
last = last.multiply(current);
}
return last.multiply(current);
return last;
}
let len = funRes ? result.length : inLen;
if (!len) {
Expand Down Expand Up @@ -189,8 +200,7 @@ export function cachedValueOf(VectorClass, getSource) {
Vector[name] = function () {
if (inProgress === X) {
inVector = inVector ? maxVector(inVector, this) : this;
last = current;
current = this;
collect[elCount - 1] = this;
}
if (inProgress === DEFAULT) {
return org.call(this);
Expand Down
11 changes: 11 additions & 0 deletions src/vector.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ class AVector {
if (quat.x === undefined) {
return this.multiplyMat3(quat);
}
if (quat.w === undefined) {
return this.multiplyVec3(quat);
}
return multQuatVec(quat, this);
}

Expand All @@ -155,6 +158,14 @@ class AVector {
);
}

multiplyVec3({ x, y, z }) {
return new this.constructor(
this.x * x,
this.y * y,
this.z * z
);
}

/**
*
* @param {AVectorType} v
Expand Down
36 changes: 36 additions & 0 deletions test/mat3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { assert } from 'chai';
import { fromOrientation, IQuaternion, calc, iquaternion, victor, degree, LEFT, FORWARD, UP, RIGHT, IMat3 } from '../src';

describe('simple Mat3 tests.', () => {

it('should lead to different results when changing order', () => {
const v1 = victor(1, 2, 3);
const v2 = victor(4, 5, 6);

const q1 = new IMat3(victor(0.5, 0, 0), victor(0, 1, 0), victor(0, 0, 1));
const q2 = new IMat3(victor(1, 0, 0), victor(0, 0, 0.5), victor(0, 1, 0));
const q3 = new IMat3(victor(0, -1, 0), victor(-0.5, 0, 0), victor(0, 0, -1));

const one = calc(() => v1 * q3);
const two = calc(() => q3 * v1);

assert.closeTo(one.x, -2, 0.001);
assert.closeTo(one.y, -0.5, 0.001);
assert.closeTo(one.z, -3, 0.001);

assert.closeTo(two.x, -1, 0.001);
assert.closeTo(two.y, -1, 0.001);
assert.closeTo(two.z, -3, 0.001);

const three = calc(() => v1 * q3 * v2);
const four = calc(() => v1 * (q3 * v2));

assert.closeTo(three.x, -8, 0.001);
assert.closeTo(three.y, -2.5, 0.001);
assert.closeTo(three.z, -18, 0.001);

assert.closeTo(four.x, -2.5, 0.001);
assert.closeTo(four.y, -8, 0.001);
assert.closeTo(four.z, -18, 0.001);
});
});
10 changes: 5 additions & 5 deletions test/quaternion.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ describe('simple Quaternion tests.', () => {
const right = iquaternion(RIGHT, degree(beta));
const forward = iquaternion(FORWARD, degree(gamma));

let rot = calc(() => up * right);
rot = calc(() => rot * forward);
rot = calc(() => rot * LEFT90);

rot = calc(() => iquaternion(rot.dir, degree(orientation)) * rot);
let rot = calc(() => up * right * forward * LEFT90);
const dir = iquaternion(rot.dir, degree(orientation));
rot = calc(() => dir * rot);

return rot;

}

it('should work with fromOrientation', () => {
Expand Down Expand Up @@ -120,5 +119,6 @@ describe('simple Quaternion tests.', () => {
assert.throws(() => (calc(() => v1 * q1 + 5)));
assert.throws(() => (calc(() => q1 * 0)));
assert.throws(() => (calc(() => q1 ** q1)));
assert.throws(() => (calc(() => q1 * q1 + v1)));
});
});

0 comments on commit 2316d99

Please sign in to comment.