refactor: "hypotenuse" is normalization

This commit is contained in:
cha0s 2019-03-27 17:53:18 -05:00
parent 759341172e
commit b042e1b1c0
3 changed files with 20 additions and 28 deletions

View File

@ -34,7 +34,7 @@ class MobileBase extends Trait {
return;
}
this.requestedMovement = Vector.scale(
Vector.hypotenuse(vector),
Vector.normalize(vector),
this.speed
);
this.entity.emit('movementRequest', this.requestedMovement);

View File

@ -146,28 +146,20 @@ export function dot(l, r) {
return l[0] * r[0] + l[1] * r[1];
}
// Get a hypotenuse unit vector. If an origin vector is passed in, the
// hypotenuse is derived from the distance to the origin.
// Get a unit vector.
//
// avocado> Vector.hypotenuse [5, 5], [6, 7]
// [-0.4472135954999579, -0.8944271909999159]
//
// avocado> Vector.hypotenuse [.5, .7]
// avocado> Vector.normalize [.5, .7]
// [0.5812381937190965, 0.813733471206735]
export function hypotenuse(unitOrDestination, origin) {
let distanceOrUnit = origin ?
sub(unitOrDestination, origin)
:
unitOrDestination;
const dp = dot(distanceOrUnit, distanceOrUnit);
export function normalize(v) {
const dp = dot(v, v);
if (0 === dp) {
return [0, 0];
}
const hypotenuse = scale(distanceOrUnit, 1 / Math.sqrt(dp));
const normalized = scale(v, 1 / Math.sqrt(dp));
// Don't let NaN poison our equations.
return [
NaN === hypotenuse[0] ? 0 : hypotenuse[0],
NaN === hypotenuse[1] ? 0 : hypotenuse[1],
NaN === normalized[0] ? 0 : normalized[0],
NaN === normalized[1] ? 0 : normalized[1],
];
}
@ -222,15 +214,15 @@ export function isNull(v) {
return 0 === v[0] || 0 === v[1];
}
export function overshot(position, hypotenuse, destination) {
export function overshot(position, normal, destination) {
const overshot = [false, false];
for (const i = 0; i < 2; ++i) {
if (hypotenuse[i] < 0) {
if (normal[i] < 0) {
if (position[i] < destination[i]) {
overshot[i] = true;
}
}
else if (hypotenuse[i] > 0) {
else if (normal[i] > 0) {
if (position[i] > destination[i]) {
overshot[i] = true;
}
@ -252,7 +244,7 @@ export function overshot(position, hypotenuse, destination) {
// avocado> Vector.toDirection4 [1, 0]
// 1
export function toDirection4(vector) {
vector = hypotenuse(vector);
vector = normalize(vector);
const x = Math.abs(vector[0]) - SQRT_2_2;
if (x > 0 && x < SQRT_2_2) {
return vector[0] > 0 ? 1 : 3;
@ -283,7 +275,7 @@ export function angle(v) {
// avocado> Vector.toDirection8 [1, 0]
// 1
export function toDirection8(v) {
v = hypotenuse(v);
v = normalize(v);
// Orient radians.
let rad = (TWO_PI + angle(v)) % TWO_PI;
rad = (rad + HALF_PI) % TWO_PI;
@ -325,10 +317,10 @@ export function fromDirection(direction) {
case 1: return [1, 0];
case 2: return [0, 1];
case 3: return [-1, 0];
case 4: return hypotenuse([1, -1]);
case 5: return hypotenuse([1, 1]);
case 6: return hypotenuse([-1, 1]);
case 7: return hypotenuse([-1, -1]);
case 4: return normalize([1, -1]);
case 5: return normalize([1, 1]);
case 6: return normalize([-1, 1]);
case 7: return normalize([-1, -1]);
}
}
@ -343,7 +335,7 @@ export function interpolate(ultimate, actual, easing = 0) {
return add(
actual,
scale(
hypotenuse(ultimate, actual),
normalize(ultimate, actual),
magnitude / easing
)
);

View File

@ -29,11 +29,11 @@ describe 'Vector', ->
expect(Vector.dot [2, 3], [4, 5]).toEqual 23
expect(Vector.hypotenuse [5, 5], [6, 7]).toEqual [
expect(Vector.normalize [5, 5], [6, 7]).toEqual [
-0.4472135954999579, -0.8944271909999159
]
expect(Vector.hypotenuse [.5, .7]).toEqual [
expect(Vector.normalize [.5, .7]).toEqual [
0.5812381937190965, 0.813733471206735
]