From d8a9a62335d15fd5d86ea727e71bad51ce0cb583 Mon Sep 17 00:00:00 2001 From: robonen Date: Wed, 10 Apr 2024 20:21:44 +0700 Subject: [PATCH] feat(packages/stdlib): mapRange util --- packages/stdlib/src/math/index.ts | 3 +- .../stdlib/src/math/mapRange/index.test.ts | 46 +++++++++++++++++++ packages/stdlib/src/math/mapRange/index.ts | 18 ++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 packages/stdlib/src/math/mapRange/index.test.ts create mode 100644 packages/stdlib/src/math/mapRange/index.ts diff --git a/packages/stdlib/src/math/index.ts b/packages/stdlib/src/math/index.ts index 0244181..701b72a 100644 --- a/packages/stdlib/src/math/index.ts +++ b/packages/stdlib/src/math/index.ts @@ -1 +1,2 @@ -export * from './clamp'; \ No newline at end of file +export * from './clamp'; +export * from './mapRange'; \ No newline at end of file diff --git a/packages/stdlib/src/math/mapRange/index.test.ts b/packages/stdlib/src/math/mapRange/index.test.ts new file mode 100644 index 0000000..55d362b --- /dev/null +++ b/packages/stdlib/src/math/mapRange/index.test.ts @@ -0,0 +1,46 @@ +import { describe, expect, it } from 'vitest'; +import { mapRange } from './index'; + +describe('mapRange', () => { + it('should map values from one range to another', () => { + // value at midpoint + expect(mapRange(5, 0, 10, 0, 100)).toBe(50); + + // value at min + expect(mapRange(0, 0, 10, 0, 100)).toBe(0); + + // value at max + expect(mapRange(10, 0, 10, 0, 100)).toBe(100); + + // value outside range (below) + expect(mapRange(-5, 0, 10, 0, 100)).toBe(0); + + // value outside range (above) + expect(mapRange(15, 0, 10, 0, 100)).toBe(100); + + // value at midpoint of negative range + expect(mapRange(75, 50, 100, -50, 50)).toBe(0); + + // value at midpoint of negative range + expect(mapRange(-25, -50, 0, 0, 100)).toBe(50); + }); + + it('should handle floating-point numbers correctly', () => { + // floating-point value + expect(mapRange(3.5, 0, 10, 0, 100)).toBe(35); + + // positive floating-point ranges + expect(mapRange(1.25, 0, 2.5, 0, 100)).toBe(50); + + // negative floating-point value + expect(mapRange(-2.5, -5, 0, 0, 100)).toBe(50); + + // negative floating-point ranges + expect(mapRange(-1.25, -2.5, 0, 0, 100)).toBe(50); + }); + + it('should handle edge cases', () => { + // input range is zero (should return output min) + expect(mapRange(5, 0, 0, 0, 100)).toBe(0); + }); +}); \ No newline at end of file diff --git a/packages/stdlib/src/math/mapRange/index.ts b/packages/stdlib/src/math/mapRange/index.ts new file mode 100644 index 0000000..cc9cddf --- /dev/null +++ b/packages/stdlib/src/math/mapRange/index.ts @@ -0,0 +1,18 @@ +import { clamp } from "../clamp"; + +/** + * Map a value from one range to another + * + * @param {number} value The value to map + * @param {number} in_min The minimum value of the input range + * @param {number} in_max The maximum value of the input range + * @param {number} out_min The minimum value of the output range + * @param {number} out_max The maximum value of the output range + * @returns {number} The mapped value + */ +export function mapRange(value: number, in_min: number, in_max: number, out_min: number, out_max: number): number { + if (in_min === in_max) + return out_min; + + return (clamp(value, in_min, in_max) - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} \ No newline at end of file