JavaScriptのMath.hypot():座標間の距離を計算する
Math.hypot()で座標間の距離やベクトルの長さを求める方法を解説。ブラウザーとNode.jsの実行手順、引数・戻り値、入力検証、数値計算の制約をコードで学べます。
Math.hypot()で何ができるか
画面上の二点がどれだけ離れているか調べたいとき、横方向と縦方向の移動量を足すだけでは直線距離になりません。横に3、縦に4離れた二点の直線距離は5です。
Math.hypot()は、引数をそれぞれ二乗して合計した値の平方根を返します。二点の座標差を渡せば距離になり、ベクトルの各成分を渡せば長さになります。ドラッグ操作の移動量、円形の範囲判定、簡単なゲームの接近判定などに使えます。
本記事では、Math.hypot()を中心に、入力を検証する距離計算の例を作ります。DOMや外部ライブラリーに依存しないため、同じコードをブラウザーとNode.jsで実行できます。
動作環境と対応バージョン
確認日は2026年10月9日です。MDNではMath.hypot()を広く利用可能な機能とし、2015年7月以降、主要ブラウザーで利用できると説明しています。現行のChrome、Edge、Firefox、Safariを利用する場合、通常は追加ライブラリーが不要です。MDNのMath.hypot()
この記事のNode.js側の実行対象は22系以降です。これは記事で採用する環境条件であり、APIが22系で初めて導入されたという意味ではありません。ブラウザー専用APIを使わないので、Node.jsでも同じ計算処理を利用できます。
古いブラウザーや組み込み環境では、呼び出す前にtypeof Math.hypot === "function"で存在を確認してください。後述のサンプルにもこの確認を入れています。存在しない環境では処理を停止し、対応環境へ変更します。
ブラウザーで実行する
対応ブラウザーで空のタブを開き、開発者ツールのConsoleを選びます。後述のJavaScriptコードを、外側のコードフェンスを除いてまとめて貼り付け、実行してください。HTMLファイルの用意やサーバーの起動は不要です。
Consoleにはログの後にundefinedが表示される場合があります。これはコード全体を評価した結果であり、距離計算の失敗ではありません。
Node.jsで実行する
Node.jsをインストールした環境で、コードをUTF-8のdistance-demo.jsとして保存します。ターミナルでそのファイルのあるディレクトリーへ移動し、次のコマンドを実行します。
node --version
node distance-demo.js最初のコマンドで22系以降か確認します。nodeが見つからない場合は、Node.jsのインストールとコマンドの検索パスを確認してください。ファイルを引数に渡す実行方法はNode.js公式の実行ガイドに記載されています。
引数と戻り値を理解する
基本の呼び出し方はMath.hypot(dx, dy)です。dxは横方向、dyは縦方向の差を表す変数名ですが、API自体に座標の概念はありません。どの値を渡すかは呼び出し側で決めます。
- 引数は可変個数で、二次元なら2個、三次元なら3個の成分を渡せます。
- 戻り値は
numberです。通常の有限数を渡した場合、結果は0以上になります。
- 引数がない場合は0を返します。
- 有限数を1個だけ渡すと、その絶対値になります。
- 数値へ変換された値が
NaNなら、無限大の引数がない限り結果もNaNです。
- 数値への変換で例外が起きない場合、正負いずれかの無限大が含まれると
Infinityになります。
これは同期処理です。戻り値はPromiseではなく、awaitやコールバックは必要ありません。また、Mathから直接呼び出す静的メソッドなので、new Math()でインスタンスを作る必要はありません。
二点の距離を計算するときは、座標そのものではなく差を渡します。点Aが(10, 20)、点Bが(13, 24)なら、差は(3, 4)です。Math.hypot(13, 24)と書くと、原点から点Bまでの距離を求める別の計算になります。
コピーして試せる距離計算
次のコードは入力検証、距離計算、範囲判定、失敗時の処理まで含む自己完結した例です。ブラウザーとNode.jsの両方で、そのまま実行する想定です。
(() => {
"use strict";
if (typeof Math.hypot !== "function") {
console.log("この環境はMath.hypot()に対応していません");
return;
}
function distance2D(ax, ay, bx, by) {
const coordinates = [ax, ay, bx, by];
if (!coordinates.every((value) => Number.isFinite(value))) {
throw new TypeError("座標には有限のnumberを指定してください");
}
const dx = bx - ax;
const dy = by - ay;
const distance = Math.hypot(dx, dy);
if (!Number.isFinite(distance)) {
throw new RangeError("距離が有限数の範囲を超えています");
}
return distance;
}
const distance = distance2D(10, 20, 13, 24);
const radius = 6;
console.log(`距離: ${distance}`);
console.log(`半径${radius}以内: ${distance <= radius}`);
console.log(`同じ点の距離: ${distance2D(10, 20, 10, 20)}`);
console.log(`三次元の長さ: ${Math.hypot(2, 3, 6)}`);
try {
distance2D(0, 0, "3", 4);
} catch (error) {
console.log(`${error.name}: ${error.message}`);
}
})();期待出力は次のとおりです。コードは本記事の作成時には実行しておらず、仕様と計算から導いた出力です。
距離: 5
半径6以内: true
同じ点の距離: 0
三次元の長さ: 7
TypeError: 座標には有限のnumberを指定してくださいコードの読み方
独自関数distance2D()は、始点のax、ayと終点のbx、byを受け取ります。座標差をMath.hypot()に渡し、計算した距離を返します。
入力チェックに使うNumber.isFinite()は、文字列を数値へ変換しません。そのため、文字列の"3"、null、NaN、Infinityを座標として拒否できます。この性質はMDNのNumber.isFinite()で確認できます。
最初の距離は、差の3と4から5になります。半径6以内の判定は5 <= 6なのでtrueです。三次元の例は、二乗の合計が4 + 9 + 36 = 49となるため7です。
最後の呼び出しでは意図的に文字列を渡します。独自関数が投げた例外をtry...catchで受け取り、処理を終了させずにエラー内容を表示します。
失敗例と数値計算の制約
暗黙の変換を入力検証に使わない
Math.hypot()自体は文字列などを数値へ変換します。そのため、入力が間違っていても必ず例外になるわけではありません。
console.log(Math.hypot("3", 4));
console.log(Math.hypot("invalid", 4));
console.log(Math.hypot(NaN, Infinity));期待出力は順に5、NaN、Infinityです。特に最後の例は、NaNが含まれるから必ずNaNになる、と考えると見落とします。これらの挙動はMDNの戻り値と使用例に示されています。
フォーム入力を扱う場合は、空欄を許すか、数値文字列を受け付けるかを先に決めてから変換してください。サンプルのdistance2D()は、変換済みの有限なnumberだけを受け付ける設計です。
大きい値でも無制限に計算できるわけではない
単純に成分を二乗すると、最終的な長さは表現できる場合でも途中計算がInfinityになることがあります。Math.hypot()は、そうした途中のオーバーフローや、小さな値の二乗が0になるアンダーフローを避ける計算に適しています。
例えば1e200を二乗するとnumberの範囲を超えますが、Math.hypot(1e200, 1e200)の結果はおよそ1.4142e200です。MDNの数値計算に関する説明
ただし、座標差を求める減算が先にオーバーフローすれば、Math.hypot()では復元できません。サンプルは結果の有限性も確認し、必要な場合はRangeErrorを投げます。また、浮動小数点の丸め誤差は残るため、境界付近の判定には用途に応じた許容差が必要です。
活用事例と次の改善
円形の操作範囲では、中心から対象までの距離と半径を比較できます。サンプルのdistance <= radiusなら、円周上の点も範囲内です。円周を除外したい場合は<へ変更します。
ドラッグ操作では、開始位置から現在位置までの距離を調べ、一定の距離を超えた時点でドラッグ開始と判断できます。ブラウザーで使う際は、両方の座標を同じ座標系にそろえてください。画面基準とページ基準の座標を混ぜると、計算できても意味の違う距離になります。
三次元データでは、各軸の差を3個渡すことで空間内の距離を求められます。ただし、緯度と経度をそのまま渡して地球上の距離をメートルで求める用途には適しません。座標系と単位に合った計算法を選ぶ必要があります。
実務へ進めるなら、まず入力の単位と許容範囲を決めることを勧めます。画面上のピクセル、ゲーム内の座標、計測値を同じ関数に渡す場合も、呼び出し側で単位をそろえれば、短い距離計算関数を安全に再利用できます。
公式参考資料
Googleの優先するニュース提供元にSEの部屋を追加
Googleで、いつも読みたい情報源を選べます。登録可否はGoogleの画面で確認できます。
候補にSEの部屋が表示されない場合は、まだ追加できません。