Skip to content

Commit

Permalink
feat(math): Add lerp methods to vectors (#959)
Browse files Browse the repository at this point in the history
  • Loading branch information
jespertheend authored Oct 31, 2024
1 parent eb60df1 commit 27af913
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 4 deletions.
23 changes: 22 additions & 1 deletion src/math/Vec2.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { clamp } from "../util/util.js";
import { clamp, lerp } from "../util/util.js";
import { Vec3 } from "./Vec3.js";
import { Vec4 } from "./Vec4.js";

Expand Down Expand Up @@ -329,6 +329,27 @@ export class Vec2 {
return this.set(x, y);
}

/**
* @param {Vec2ParameterSingle} vecA
* @param {Vec2ParameterSingle} vecB
* @param {number} t
*/
static lerp(vecA, vecB, t) {
const vA = new Vec2(vecA);
return vA.lerp(vecB, t);
}

/**
* @param {Vec2ParameterSingle} vector
* @param {number} t
*/
lerp(vector, t) {
const vecB = new Vec2(vector);
const x = lerp(this._x, vecB.x, t);
const y = lerp(this._y, vecB.y, t);
return this.set(x, y);
}

/**
* Sets each component to the minimum of the two vectors.
* @param {Vec2Parameters} args
Expand Down
24 changes: 23 additions & 1 deletion src/math/Vec3.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { clamp } from "../util/util.js";
import { clamp, lerp } from "../util/util.js";
import { Mat4 } from "./Mat4.js";
import { Quat } from "./Quat.js";
import { Vec2 } from "./Vec2.js";
Expand Down Expand Up @@ -434,6 +434,28 @@ export class Vec3 {
return this.set(x, y, z);
}

/**
* @param {Vec3ParameterSingle} vecA
* @param {Vec3ParameterSingle} vecB
* @param {number} t
*/
static lerp(vecA, vecB, t) {
const vA = new Vec3(vecA);
return vA.lerp(vecB, t);
}

/**
* @param {Vec3ParameterSingle} vector
* @param {number} t
*/
lerp(vector, t) {
const vecB = new Vec3(vector);
const x = lerp(this._x, vecB.x, t);
const y = lerp(this._y, vecB.y, t);
const z = lerp(this._z, vecB.z, t);
return this.set(x, y, z);
}

/**
* Sets each component to the minimum of the two vectors.
* @param {Vec3Parameters} args
Expand Down
24 changes: 24 additions & 0 deletions src/math/Vec4.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Vec2 } from "./Vec2.js";
import { Vec3 } from "./Vec3.js";
import { Mat4 } from "./Mat4.js";
import { Quat } from "./Quat.js";
import { lerp } from "../util/util.js";

/**
* @typedef {() => Vec4} vec4SetEmptySignature
Expand Down Expand Up @@ -413,6 +414,29 @@ export class Vec4 {
return this.set(x, y, z, w);
}

/**
* @param {Vec4ParameterSingle} vecA
* @param {Vec4ParameterSingle} vecB
* @param {number} t
*/
static lerp(vecA, vecB, t) {
const vA = new Vec4(vecA);
return vA.lerp(vecB, t);
}

/**
* @param {Vec4ParameterSingle} vector
* @param {number} t
*/
lerp(vector, t) {
const vecB = new Vec4(vector);
const x = lerp(this._x, vecB.x, t);
const y = lerp(this._y, vecB.y, t);
const z = lerp(this._z, vecB.z, t);
const w = lerp(this._w, vecB.w, t);
return this.set(x, y, z, w);
}

/**
* Sets each component to the minimum of the two vectors.
* @param {Vec4Parameters} args
Expand Down
44 changes: 44 additions & 0 deletions test/unit/src/math/Vec2.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,45 @@ Deno.test({
},
});

Deno.test({
name: "lerp()",
fn() {
const tests = [
{ a: [1, 1], b: [2, 2], t: 0, result: [1, 1] },
{ a: [1, 1], b: [2, 2], t: 0.5, result: [1.5, 1.5] },
{ a: [1, 1], b: [2, 2], t: 2, result: [3, 3] },
{ a: [0, 1], b: [2, 3], t: 0.5, result: [1, 2] },
];

for (const { a, b, t, result } of tests) {
const vec = new Vec2(a);
vec.lerp(b, t);

assertVecAlmostEquals(vec, result);
}
},
});

Deno.test({
name: "static lerp()",
fn() {
const tests = [
{ a: [1, 1], b: [2, 2], t: 0, result: [1, 1] },
{ a: [1, 1], b: [2, 2], t: 0.5, result: [1.5, 1.5] },
{ a: [1, 1], b: [2, 2], t: 2, result: [3, 3] },
{ a: [0, 1], b: [3, 4], t: 0.5, result: [1.5, 2.5] },
{ a: new Vec3(1, 1, 1), b: new Vec4(2, 2, 2, 2), t: 0.5, result: [1.5, 1.5] },
{ a: [0, 0, 0], b: [2, 2, 2, 2], t: 0.5, result: [1, 1] },
];

for (const { a, b, t, result } of tests) {
const vec = Vec2.lerp(a, b, t);

assertVecAlmostEquals(vec, result);
}
},
});

Deno.test({
name: "min()",
fn() {
Expand Down Expand Up @@ -918,6 +957,11 @@ Deno.test({
vec.subVector(new Vec2(0, 1));
expectedResult.push(0x01);

vec.set(0, 0);
vec.lerp([0, 1], 0.5);
expectedResult.push(0x11);
expectedResult.push(0x01);

// vec.cross(1, 2, 3);
// expectedResult.push(0x11);

Expand Down
46 changes: 46 additions & 0 deletions test/unit/src/math/Vec3.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,45 @@ Deno.test({
},
});

Deno.test({
name: "lerp()",
fn() {
const tests = [
{ a: [1, 1, 1], b: [2, 2, 2], t: 0, result: [1, 1, 1] },
{ a: [1, 1, 1], b: [2, 2, 2], t: 0.5, result: [1.5, 1.5, 1.5] },
{ a: [1, 1, 1], b: [2, 2, 2], t: 2, result: [3, 3, 3] },
{ a: [0, 1, 2], b: [3, 4, 5], t: 0.5, result: [1.5, 2.5, 3.5] },
];

for (const { a, b, t, result } of tests) {
const vec = new Vec3(a);
vec.lerp(b, t);

assertVecAlmostEquals(vec, result);
}
},
});

Deno.test({
name: "static lerp()",
fn() {
const tests = [
{ a: [1, 1, 1], b: [2, 2, 2], t: 0, result: [1, 1, 1] },
{ a: [1, 1, 1], b: [2, 2, 2], t: 0.5, result: [1.5, 1.5, 1.5] },
{ a: [1, 1, 1], b: [2, 2, 2], t: 2, result: [3, 3, 3] },
{ a: [0, 1, 2], b: [3, 4, 5], t: 0.5, result: [1.5, 2.5, 3.5] },
{ a: new Vec2(1, 1), b: new Vec4(2, 2, 2, 2), t: 0.5, result: [1.5, 1.5, 1] },
{ a: [0, 0], b: [2, 2, 2, 2], t: 0.5, result: [1, 1, 1] },
];

for (const { a, b, t, result } of tests) {
const vec = Vec3.lerp(a, b, t);

assertVecAlmostEquals(vec, result);
}
},
});

Deno.test({
name: "min()",
fn() {
Expand Down Expand Up @@ -1051,8 +1090,15 @@ Deno.test({
vec.subVector(new Vec3(0, 1, 0));
expectedResult.push(0x010);

vec.set(0, 0, 0);
vec.lerp([0, 1, 1], 0.5);
expectedResult.push(0x111);
expectedResult.push(0x011);

vec.set(2.5, 8.5, 8.5);
vec.cross(1, 2, 3);
expectedResult.push(0x111);
expectedResult.push(0x111);

vec.set(1, 2, 3);
vec.projectOnVector(3, 2, 1);
Expand Down
45 changes: 43 additions & 2 deletions test/unit/src/math/Vec4.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,45 @@ Deno.test({
},
});

Deno.test({
name: "lerp()",
fn() {
const tests = [
{ a: [1, 1, 1, 1], b: [2, 2, 2, 2], t: 0, result: [1, 1, 1, 1] },
{ a: [1, 1, 1, 1], b: [2, 2, 2, 2], t: 0.5, result: [1.5, 1.5, 1.5, 1.5] },
{ a: [1, 1, 1, 1], b: [2, 2, 2, 2], t: 2, result: [3, 3, 3, 3] },
{ a: [0, 1, 2, 3], b: [4, 5, 6, 7], t: 0.5, result: [2, 3, 4, 5] },
];

for (const { a, b, t, result } of tests) {
const vec = new Vec4(a);
vec.lerp(b, t);

assertVecAlmostEquals(vec, result);
}
},
});

Deno.test({
name: "static lerp()",
fn() {
const tests = [
{ a: [1, 1, 1, 1], b: [2, 2, 2, 2], t: 0, result: [1, 1, 1, 1] },
{ a: [1, 1, 1, 1], b: [2, 2, 2, 2], t: 0.5, result: [1.5, 1.5, 1.5, 1.5] },
{ a: [1, 1, 1, 1], b: [2, 2, 2, 2], t: 2, result: [3, 3, 3, 3] },
{ a: [0, 1, 2, 3], b: [4, 5, 6, 7], t: 0.5, result: [2, 3, 4, 5] },
{ a: new Vec2(1, 1), b: new Vec3(2, 2, 2), t: 0.5, result: [1.5, 1.5, 1, 1] },
{ a: [0, 0, 0], b: [2, 2, 2, 2], t: 0.5, result: [1, 1, 1, 1.5] },
];

for (const { a, b, t, result } of tests) {
const vec = Vec4.lerp(a, b, t);

assertVecAlmostEquals(vec, result);
}
},
});

Deno.test({
name: "min()",
fn() {
Expand Down Expand Up @@ -950,8 +989,10 @@ Deno.test({
vec.subVector(new Vec4(0, 1, 0, 0));
expectedResult.push(0x0100);

// vec.cross(1, 2, 3, 4);
// expectedResult.push(0x1111);
vec.set(0, 0, 0, 0);
vec.lerp([0, 1, 1, 0], 0.5);
expectedResult.push(0x1111);
expectedResult.push(0x0110);

vec.set(1, 2, 3, 4);
vec.projectOnVector(4, 3, 2, 1);
Expand Down

0 comments on commit 27af913

Please sign in to comment.