Skip to content

Commit 967cf91

Browse files
committed
feat(operator): prepare operator handling for mixed calc
1 parent 1e22cce commit 967cf91

File tree

4 files changed

+94
-26
lines changed

4 files changed

+94
-26
lines changed

src/operator.js

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
/* eslint no-param-reassign: 0 */
33
/* eslint getter-return: 0 */
44
/* eslint new-cap: 0 */
5+
/* eslint no-prototype-builtins: 0 */
56

67
const X = 0;
78
const Y = 1;
89
const Z = 2;
910
const DEFAULT = 3;
11+
const VECTOR_LENGTH = Symbol('vector length');
1012

1113
let inProgress = DEFAULT;
1214
let inVector;
@@ -21,10 +23,21 @@ function handleProgess(progess, alg, resVec) {
2123
return alg(resVec);
2224
}
2325

26+
function getVectorLength(vec) {
27+
return vec[VECTOR_LENGTH] !== 2 ? 3 : 2;
28+
}
29+
30+
function maxVector(v1, v2) {
31+
if (getVectorLength(v1) > getVectorLength(v2)) {
32+
return v1;
33+
}
34+
return v2;
35+
}
36+
2437
/**
2538
* @param {() => number} alg
26-
* @param {{ x: number, y: number, z: number }=} result
27-
* @return {{ x: number, y: number, z: number } | number}
39+
* @param {{ x: number, y: number, z: number } | { x: number, y: number }=} result
40+
* @return {{ x: number, y: number, z: number } | { x: number, y: number } | number}
2841
*/
2942
export function operatorCalc(alg, result) {
3043
if (typeof alg !== 'function') {
@@ -43,19 +56,39 @@ export function operatorCalc(alg, result) {
4356
return x;
4457
}
4558

59+
let calcZ = false;
60+
if (inVector) {
61+
calcZ = getVectorLength(inVector) !== 2;
62+
} else {
63+
calcZ = result.length !== 2;
64+
}
65+
4666
const y = handleProgess(Y, alg, resVec);
47-
const z = handleProgess(Z, alg, resVec);
4867

49-
if (noRes) {
50-
return new inVector.constructor(x, y, z);
51-
}
52-
if (funRes) {
53-
return result(x, y, z);
54-
}
68+
if (!calcZ) {
69+
if (noRes) {
70+
return new inVector.constructor(x, y);
71+
}
72+
if (funRes) {
73+
return result(x, y);
74+
}
5575

56-
result.x = x;
57-
result.y = y;
58-
result.z = z;
76+
result.x = x;
77+
result.y = y;
78+
} else {
79+
const z = handleProgess(Z, alg, resVec);
80+
81+
if (noRes) {
82+
return new inVector.constructor(x, y, z);
83+
}
84+
if (funRes) {
85+
return result(x, y, z);
86+
}
87+
88+
result.x = x;
89+
result.y = y;
90+
result.z = z;
91+
}
5992
return result;
6093
} finally {
6194
inProgress = DEFAULT;
@@ -70,14 +103,17 @@ export function cachedValueOf(VectorClass) {
70103

71104
Vector[name] = function () {
72105
if (inProgress === X) {
73-
inVector = this;
106+
inVector = inVector ? maxVector(inVector, this) : this;
74107
return this.x;
75108
}
76109
if (inProgress === Y) {
77110
return this.y;
78111
}
79112
if (inProgress === Z) {
80-
return this.z;
113+
if (this[VECTOR_LENGTH] !== 2) {
114+
return this.z;
115+
}
116+
return 0;
81117
}
82118
return org.call(this);
83119
};
@@ -129,3 +165,9 @@ export function cachedGetter(VectorClass, name) {
129165
get: bindCache(org)
130166
});
131167
}
168+
169+
export function defineVectorLength(VectorClass, value) {
170+
const Vector = VectorClass.prototype;
171+
172+
Object.defineProperty(Vector, VECTOR_LENGTH, { value });
173+
}

src/point.js

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import {
2-
cachedMethod, cachedGetter, cachedValueOf, operatorCalc
2+
cachedMethod,
3+
cachedGetter,
4+
cachedValueOf,
5+
operatorCalc,
6+
defineVectorLength
37
} from './operator';
48
import formatNumber from './formatter';
59

@@ -49,8 +53,8 @@ class APoint {
4953
*/
5054
constructor(x, y) {
5155
if (typeof x === 'function') {
52-
operatorCalc(x, (...args) => {
53-
this[AXES] = args;
56+
operatorCalc(x, (nx, ny) => {
57+
this[AXES] = [nx, ny];
5458
});
5559
} else {
5660
this[AXES] = [x || 0, y || 0];
@@ -69,7 +73,7 @@ class APoint {
6973
*/
7074
normalize() {
7175
const { length } = this;
72-
return new this.constructor(this.x / length, this.y / length, this.z / length);
76+
return new this.constructor(this.x / length, this.y / length);
7377
}
7478

7579
/**
@@ -128,10 +132,10 @@ class APoint {
128132

129133
/**
130134
*
131-
* @returns {[number, number, number]}
135+
* @returns {[number, number]}
132136
*/
133137
toArray() {
134-
return [this.x, this.y, this.z];
138+
return [this.x, this.y];
135139
}
136140

137141
/**
@@ -190,14 +194,31 @@ class APoint {
190194
get len() {
191195
return this.length;
192196
}
197+
198+
/**
199+
*
200+
* @throws GetNotImplementedError
201+
*/
202+
get z() {
203+
throw new Error('get z() not implemented');
204+
}
205+
206+
/**
207+
*
208+
* @throws SetNotImplementedError
209+
*/
210+
set z(_) {
211+
throw new Error('set z() not implemented');
212+
}
193213
}
194214

195215
cachedValueOf(APoint);
216+
defineVectorLength(APoint, 2);
196217
cachedMethod(APoint, 'dot');
197-
cachedMethod(APoint, 'toAngle');
198218
cachedMethod(APoint, 'angleTo');
199219
cachedMethod(APoint, 'distance');
200220
cachedMethod(APoint, 'toArray');
221+
cachedMethod(APoint, 'getRad');
201222
cachedGetter(APoint, 'length');
202223
cachedGetter(APoint, 'lengthSq');
203224

src/vector.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import {
2-
cachedMethod, cachedGetter, cachedValueOf, operatorCalc
2+
cachedMethod,
3+
cachedGetter,
4+
cachedValueOf,
5+
operatorCalc,
6+
defineVectorLength
37
} from './operator';
48
import formatNumber from './formatter';
59

@@ -26,8 +30,8 @@ class AVector {
2630
*/
2731
constructor(x, y, z) {
2832
if (typeof x === 'function') {
29-
operatorCalc(x, (...args) => {
30-
this[AXES] = args;
33+
operatorCalc(x, (nx, ny, nz) => {
34+
this[AXES] = [nx, ny, nz];
3135
});
3236
} else {
3337
this[AXES] = [x || 0, y || 0, z || 0];
@@ -239,6 +243,7 @@ class AVector {
239243
}
240244

241245
cachedValueOf(AVector);
246+
defineVectorLength(AVector, 3);
242247
cachedMethod(AVector, 'dot');
243248
cachedMethod(AVector, 'cross');
244249
cachedMethod(AVector, 'crossNormalize');

test/point.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { assert } from 'chai';
22
import { Point, IPoint, calc } from '../src/point';
33

44
const pointTest = (Vec2) => {
5-
it('should create x y z values', () => {
5+
it('should create x y values', () => {
66
const pos = new Vec2(5, 6);
77
assert.equal(pos.x, 5);
88
assert.equal(pos.y, 6);
@@ -115,7 +115,7 @@ describe('special Point test.', () => {
115115
assert.equal(pos.y, 28);
116116
});
117117

118-
it('should change x y z values when calling local calc method', () => {
118+
it('should change x y values when calling local calc method', () => {
119119
const pos = new Point(5, 6);
120120
const res = pos.calc(p => p * 25);
121121

0 commit comments

Comments
 (0)