みさご解体新書

範囲変更による値のマッピング

概要

ある範囲の中にある、特定の値の位置(割合)を A として、別の範囲での位置 A に存在する値を返す。

コード例

// 正規化
function norm(a: number, b: number, v: number): number {
  return (v - a) / (b - a);
}

// 線形補間
function lerp(a: number, b: number, t: number): number {
  return a + (b - a) * t;
}

// 範囲変更による値のマッピング
function map(v: number, a: number, b: number, c: number, d: number): number {
  return lerp(c, d, norm(a, b, v));
}

a ~ b の範囲で v が存在する位置の割合 r を調べ、 c ~ d の範囲で割合 r の位置にある値を返却する。

function map2(v: number, a: number, b: number, c: number, d: number): number {
  v = Math.max(v, a);
  v = Math.min(v, b);
  v = map(v, a, b, c, d);
  return v;
}

v に a ~ b の範囲外の値が指定された場合は、計算結果も c ~ d の範囲外の値になる。

そうならないように、クランプ処理を付けたコードになる。

解説/アルゴリズム

まず正規化を使用して、 a ~ b の範囲の中で、 v がある位置を割合 r として求める。

次に線形補間を使用して、 c ~ d の範囲の中で、上で求めた割合 r の位置にある値を返却する。

内部で利用しているアルゴリズム

正規化, 線形補間, クランプ処理