LoginSignup
3
2

More than 3 years have passed since last update.

【TC39 Proposals】Math Extensions

Last updated at Posted at 2019-10-07
1 / 12

注意書き

2019 年 10 月 9 日に開催の #tc39_study 用に作成した資料です。
執筆時点で TC39 の Proposals に上がっている機能を紹介します。
将来的に JavaScript(ECMAScript)に取り入れられるかもしれませんし、取り入れられないかもしれませんし、紹介内容から仕様が大きく変更になるかもしれません。
TC39 の承認プロセスについては、https://tc39.es/process-document/ をご覧ください。


Math Extensions

Math に 4 つの関数と 2 つの定数を追加する Proposal です。
コンピュータグラフィックス方面で時々使うような処理が追加されます。
本記事の執筆時点で Stage 1 です。


Math.clamp(x, lower, upper)

xlower を下回ったときは lower を、upper を上回った時は upper を、どちらでもないときは x を返すような関数です。
値が設定された下限と上限を超えないように変換するときに有用です。
Math.minMath.max を使えば同等の処理ができます。

使い方

console.log(Math.clamp(0, -100, 100))
// -> 0

console.log(Math.clamp(-200, -100, 100))
// -> -100

console.log(Math.clamp(200, -100, 100))
// -> 100

console.log(Math.clamp(NaN, -100, 100))
// -> NaN

console.log(Math.clamp(0, NaN, 100))
// -> NaN

console.log(Math.clamp(0, -100, NaN))
// -> NaN

同等の処理

const clamp = (x, lower, upper) => {
  return Math.min(Math.max(x, lower), upper)
}
console.log(clamp(0, -100, 100))
console.log(clamp(-200, -100, 100))
console.log(clamp(200, -100, 100))
console.log(clamp(NaN, -100, 100))
console.log(clamp(0, NaN, 100))
console.log(clamp(0, -100, NaN))

Math.scale(x, inLow, inHigh, outLow, outHigh)

x を線形変換した値を返します。
2つの数直線があり、片方に xinLowinHigh が、もう片方に youtLowoutHight があり、inLowoutLowinHighoutHigh がそれぞれ対応しているとき、x に対応する y を計算するイメージです。

scale.png

以下の関係が成り立ちます。

\frac{x - \text{inLow}}{\text{inHigh} - \text{inLow}} = \frac{y - \text{outLow}}{\text{outHigh} - \text{outLow}}

使い方

console.log(Math.scale(50, 0, 100, -10, 10))
// -> 0

console.log(Math.scale(200, 0, 100, -10, 10))
// -> 30

console.log(Math.scale(80, 0, 100, 10, -10))
// -> -6

console.log(Math.scale(NaN, 0, 100, -10, 10))
// -> NaN

console.log(Math.scale(50, NaN, 100, -10, 10))
// -> NaN

console.log(Math.scale(50, 0, NaN, -10, 10))
// -> NaN

console.log(Math.scale(50, 0, 100, NaN, 10))
// -> NaN

console.log(Math.scale(50, 0, 100, -10, NaN))
// -> NaN

console.log(Math.scale(Infinity, 0, 100, -10, 10))
// -> Infinity

console.log(Math.scale(-Infinity, 0, 100, -10, 10))
// -> -Infinity

console.log(Math.scale(50, -Infinity, 100, -10, 10))
// -> NaN

console.log(Math.scale(50, 0, Infinity, -10, 10))
// -> -10

console.log(Math.scale(50, 0, 100, -Infinity, 10))
// -> NaN

console.log(Math.scale(50, 0, 100, -10, Infinity))
// -> Infinity

Math.radians(degrees)

degrees をラジアンに変換した値を返します。

使い方

console.log(Math.degrees(-1))
// -> -57.29577951308232

console.log(Math.degrees(0))
// -> 0

console.log(Math.degrees(1))
// -> 57.29577951308232

console.log(Math.degrees(Math.PI))
// -> 180

console.log(Math.degrees(2 * Math.PI))
// -> 360

console.log(Math.degrees(3 * Math.PI))
// -> 540

console.log(Math.degrees(NaN))
// -> NaN

console.log(Math.degrees(+Infinity))
// -> Infinity

console.log(Math.degrees(-Infinity))
// -> -Infinity

Math.degrees(radians)

radians を度数に変換した値を返します。

使い方

console.log(Math.radians(-120))
// -> -2.0943951023931953

console.log(Math.radians(0))
// -> 0

console.log(Math.radians(120))
// -> 2.0943951023931953

console.log(Math.radians(240))
// -> 4.1887902047863905

console.log(Math.radians(360))
// -> 6.283185307179586

console.log(Math.radians(480))
// -> 8.377580409572781

console.log(Math.radians(NaN))
// -> NaN

console.log(Math.radians(+Infinity))
// -> Infinity

console.log(Math.radians(-Infinity))
// -> -Infinity

Math.RAD_PER_DEG

1° あたりのラジアンを表す定数です。

\frac{180}{\pi} = 57.29577951308232

Math.DEG_PER_RAD

1 ラジアンあたりの度数を表す定数です。

\frac{\pi}{180} = 0.0174532925199432

Polyfill

core-js/proposals/math-extensions を読み込んでください。

CommonJS

require('core-js/proposals/math-extensions')

ES Modules

import 'core-js/proposals/math-extensions'

所感

JavaScriptでお絵描きしてたらたまに必要になる。
個人的に特にscale は、これのためだけにd3-scaleを入れたりするので標準で入ってくれると嬉しい。


参考情報

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2