Skip to content

Commit

Permalink
feat: Add traditional lerp functions for ease of use
Browse files Browse the repository at this point in the history
  • Loading branch information
eonarheim committed Nov 11, 2024
1 parent 1fd83fd commit 8020560
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Added

- Added new `ex.lerp(...)`, `ex.inverseLerp(...)`, and `ex.remap(...)` for numbers
- Added new `ex.lerpVector(...)`,` ex.inverseLerpVector(...)`, and `ex.remapVector(...)` for `ex.Vector`
- Added new `actor.actions.flash(...)` `Action` to flash a color for a period of time
- Added a new `ex.NineSlice` `Graphic` for creating arbitrarily resizable rectangular regions, useful for creating UI, backgrounds, and other resizable elements.
```typescript
Expand Down
1 change: 1 addition & 0 deletions src/engine/Math/Index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export * from './line-segment';
export * from './projection';
export * from './ray';
export * from './util';
export * from './lerp';
79 changes: 79 additions & 0 deletions src/engine/Math/lerp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { Vector } from './vector';

/**
* Linear interpolation between `a` and `b`, at `time = 0` the value will be `a` at `time = 1` the value will be `b`
* @param a
* @param b
* @param time
*/
export function lerp(a: number, b: number, time: number): number {
return (1 - time) * a + b * time;
}

/**
* Linear interpolation between `a` and `b`, at `time = 0` the value will be `a` at `time = 1` the value will be `b`
* @param a
* @param b
* @param time
*/
export function lerpVector(a: Vector, b: Vector, time: number): Vector {
return a.scale(1 - time).add(b.scale(time));
}

/**
* Inverse of a linear interpolation, given a `value` in between `a` and `b` return how close to `a` or `b` the `value` is.
*
* Example: `a=1`, `b=5`, `value=4` will return `.75`
* @param a
* @param b
* @param value
*/
export function inverseLerp(a: number, b: number, value: number): number {
return (value - a) / (b - a);
}

/**
* Inverse of a linear interpolation, given a `value` in between `a` and `b` return how close to `a` or `b` the `value` is.
*
* **Warning** assumes that the `value` vector is co-linear with vector `a` and `b`
*
* Example: `a=1`, `b=5`, `value=4` will return `.75`
* @param a
* @param b
* @param value
*/
export function inverseLerpVector(a: Vector, b: Vector, value: Vector): number {
const numerator = value.sub(a);
const denominator = b.sub(a);
const x = numerator.x / denominator.x;
const y = numerator.y / denominator.y;
return Math.min(x, y);
}

/**
* Remaps a value from a source domain to a destination
* @param minSource
* @param maxSource
* @param minDestination
* @param maxDestination
* @param value
*/
export function remap(minSource: number, maxSource: number, minDestination: number, maxDestination: number, value: number): number {
const time = inverseLerp(minSource, maxSource, value);
return lerp(minDestination, maxDestination, time);
}

/**
* Remaps a value from a source domain to a destination
*
* **Warning** assumes that the `value` vector is co-linear with vector `minSource` and `maxSource`
* @param minSource
* @param maxSource
* @param minDestination
* @param maxDestination
* @param value
*/
export function remapVector(minSource: Vector, maxSource: Vector, minDestination: Vector, maxDestination: Vector, value: Vector): Vector {
const time = inverseLerpVector(minSource, maxSource, value);
return lerpVector(minDestination, maxDestination, time);
}

0 comments on commit 8020560

Please sign in to comment.