JavaScript

JavaScriptのMath.acosh():曲線の高さから横方向の位置を逆算する

この記事でわかること

Math.acosh()で逆双曲線余弦を求める方法を解説。曲線の高さから位置を逆算する実例、引数・戻り値、ブラウザーとNode.jsの実行手順、入力範囲や計算精度の注意点を学べます。

目的:曲線の出力から入力を求める

グラフを描くプログラムでは、横方向の位置から高さを計算するだけでなく、「この高さになる位置はどこか」を調べたい場合があります。曲線を少しずつ走査する方法もありますが、逆関数を使えるなら直接計算できます。

Math.acosh()は逆双曲線余弦を返す関数です。名前は難しく見えますが、ここでは「双曲線余弦で作った曲線の値から、元の入力を求める道具」と考えると使い道がわかります。

この記事では、説明用にheight = scale * (cosh(position / scale) - 1)という曲線を定義します。scaleは曲線の形を決める正の値、positionは中央からの横方向の位置、heightは中央からの高さです。高さと位置は同じ単位で扱います。

この式を変形すると、右側の位置はposition = scale * Math.acosh(1 + height / scale)で求められます。数値探索の刻み幅を決める必要がなく、計算の目的もコードに表れます。

動作環境と対応状況

Math.acosh()はブラウザー専用APIではなく、JavaScriptの組み込み関数です。ブラウザーとNode.jsの両方で使用でき、DOMや外部ライブラリーには依存しません。

2026年10月30日時点で確認したMDNのMath.acosh()は、主要ブラウザー間で2015年7月から広く利用できる機能としています。現在のChrome、Edge、Firefox、Safariを対象にできます。

この記事のNode.js側の実行対象は22系以降です。これは記事のサンプルで対象とするバージョンであり、この関数が初めて導入されたバージョンという意味ではありません。Node.jsがV8を通してJavaScriptの言語機能を提供する仕組みは、Node.jsのECMAScript解説で確認できます。

古い組み込みブラウザーなども対象にする場合は、使用前にtypeof Math.acosh === "function"で存在を確認してください。未対応環境では関数を呼び出せません。

引数・戻り値と数学的な意味

呼び出し方

構文はMath.acosh(x)です。引数は1つで、通常は1以上の数値を渡します。インスタンスを作らず、Mathから直接呼び出します。

戻り値は数値です。有限のxが1以上なら、「双曲線余弦を計算するとxになる、0以上の入力」に相当します。特殊値も含めた代表例は次のとおりです。

  • Math.acosh(1)は0を返します。
  • Math.acosh(2)は約1.3169578969を返します。
  • Math.acosh(0)のように1未満を渡すとNaNを返します。
  • Math.acosh(Infinity)はInfinityを返します。

入力範囲外であることを、必ず例外で知らせる関数ではありません。呼び出しが終わったという理由だけで、有効な計算結果だと判断しないことが大切です。これらの動作はMDNの引数・戻り値と使用例に記載されています。

なぜ右側の位置だけが求まるのか

双曲線余弦は正負の入力で同じ値を取ります。定義はcosh(t) = (exp(t) + exp(-t)) / 2で、tを負にしても2つの項が入れ替わるだけです。この関係はMDNの双曲線余弦の説明でも確認できます。

そのため、中央から同じ高さにある位置は通常、左右に存在します。Math.acosh()が選ぶのは0以上の入力です。今回の式で得られる値を右側の位置とし、左側が必要なら符号を反転させます。高さが0の場合は中央の1か所です。

コピーして実行するサンプル

次のコードは、入力検証、位置の計算、表示、失敗例まで含む自己完結したサンプルです。rightPositionAtHeight()のheightは0以上の有限数、scaleは0より大きい有限数に限定しています。

JavaScript
(() => {
  "use strict";

  if (typeof Math.acosh !== "function") {
    console.log("この環境はMath.acosh()に対応していません");
    return;
  }

  function rightPositionAtHeight(height, scale) {
    if (!Number.isFinite(height) || height < 0) {
      throw new RangeError("heightは0以上の有限数にしてください");
    }

    if (!Number.isFinite(scale) || scale <= 0) {
      throw new RangeError("scaleは0より大きい有限数にしてください");
    }

    const input = 1 + height / scale;
    if (!Number.isFinite(input)) {
      throw new RangeError("計算途中の値が大きすぎます");
    }

    const position = scale * Math.acosh(input);
    if (!Number.isFinite(position)) {
      throw new RangeError("位置が数値の表現範囲を超えました");
    }

    return position;
  }

  const scale = 10;
  for (const height of [0, 10, 15]) {
    const position = rightPositionAtHeight(height, scale);
    console.log(`高さ=${height}, 右側の位置=${position.toFixed(3)}`);
  }

  try {
    rightPositionAtHeight(-1, scale);
  } catch (error) {
    if (error instanceof Error) {
      console.log(`${error.name}: ${error.message}`);
    } else {
      throw error;
    }
  }
})();

ブラウザーでの実行方法

対応ブラウザーで空のページなどを開き、開発者ツールのConsoleを選択します。上のJavaScript全体を貼り付けて実行してください。ページ内の要素を読み書きしないため、HTMLを別途用意する必要はありません。

コード全体を即時実行関数で囲んでいるので、Consoleで繰り返し実行しても、トップレベルの同名変数の再宣言を避けられます。実行後にConsoleが追加表示するundefinedは、サンプルが出力した行には含めません。

Node.jsでの実行方法

Node.js 22系以降を用意し、上のコードをUTF-8のacosh-demo.cjsとして保存します。ターミナルでそのファイルのあるディレクトリーへ移動し、次を実行してください。パッケージの追加やビルドは不要です。

Shell
node acosh-demo.cjs

ファイル名をnodeへ渡す実行方法は、Node.js公式のスクリプト実行ガイドに沿っています。

期待出力

対応環境では、次の4行を想定しています。これは公式の数値例と式から確認した期待値であり、本記事作成時にコードを実行して得たログではありません。

CODE
高さ=0, 右側の位置=0.000
高さ=10, 右側の位置=13.170
高さ=15, 右側の位置=15.668
RangeError: heightは0以上の有限数にしてください

高さ10では引数が1 + 10 / 10、つまり2になります。その逆双曲線余弦に10を掛けると約13.169579です。高さ15では引数が2.5となり、約15.667992を得ます。表示時だけ小数点以下3桁に丸め、関数の戻り値自体は丸めていません。

失敗例と制約

範囲外の値は自動修正しない

Math.acosh(0.5)はNaNになります。サンプルでは高さが負なら計算前に例外へ変えています。範囲外の値を無条件に1へ置き換えると、誤った入力から中央の位置を返してしまい、原因を見つけにくくなります。

文字列の"10"も、サンプルの関数では受け付けません。フォームからの入力は文字列になるため、呼び出す側で空欄かどうかを確認してから数値へ変換する設計が必要です。

極端な値では精度が失われる

有限数どうしでも、height / scaleや最後の乗算が大きすぎればInfinityになる場合があります。サンプルは途中と最後の値を確認して、その状態を検出します。

一方、height / scaleが極端に小さい場合は、1を足した時点で丸められて1になる可能性があります。その場合、正の高さでも結果が0になるため、有限数チェックだけでは精度を保証できません。扱う値の範囲を業務側で決め、境界付近では必要な誤差に収まるか別途評価してください。

MDNのMathの説明では、数学関数の精度が実装に依存する点も説明されています。計算結果の小数点以下すべてが環境間で一致すると仮定せず、比較には用途に合う許容誤差を使います。

この処理は同期計算です。Promiseやawaitは不要で、入力エラーは呼び出し元のtry...catchで扱えます。大量の点を処理する場合は同期処理が続く時間も考慮してください。

活用事例と設計上の改善案

活用できるのは、曲線の式があらかじめ決まっているグラフ教材や可視化ツールです。利用者が高さを指定したときに、対応する左右の位置へマーカーを置く、といった操作を実装できます。

今回の関数は右側の位置だけを返すため、画面表示、単位の付与、左右の選択を呼び出し側で決められます。次に改善するなら、入力欄の検証と表示用の丸めを計算部分から分離すると、ブラウザーとNode.jsで同じ計算を使いやすくなります。

ただし、任意の曲線を逆算できる関数ではありません。まず対象の式が双曲線余弦で表せるかを確認し、適用できる場合に使います。計算式が違う場合は、その式に合う逆関数や数値解法を選ぶ必要があります。

公式参考資料

PREFERRED SOURCES

Googleの優先するニュース提供元にSEの部屋を追加

Googleで、いつも読みたい情報源を選べます。登録可否はGoogleの画面で確認できます。

Googleの設定画面で確認する 新しいタブで開きます

候補にSEの部屋が表示されない場合は、まだ追加できません。

y.
WRITTEN BY

y_ymo10

SEの部屋で、HTML・CSSからJavaScript・React・Next.jsまで、Web制作の開発ノートを公開しています。

ほかの開発ノートを読む →