【PHP実践|実務向け】PHPで任意の座標を回転させる:幾何学計算の実装テクニック

導入

Webアプリケーションにおいて、画像処理やグラフ生成、あるいはゲームロジックの実装を行う際、特定の中心点を基準として座標を回転させる処理が必要になるケースがあります。例えば、GDライブラリを用いた図形の描画や、動的な位置計算を行う際、標準関数だけでは表現しきれないロジックを自前で実装しなければなりません。本記事では、数学的なアプローチを用いて、PHPで任意の座標を回転させるための実用的な関数とその仕組みを解説します。

基礎知識

座標の回転には「三角関数」の知識が不可欠です。ある点(x2, y2)を点(x1, y1)を中心に回転させる場合、以下のステップを踏みます。
1. 回転前の相対座標を算出する(x2 – x1, y2 – y1)。
2. 回転行列を用いて新しい相対座標を計算する。
3. 最後に中心点の座標を足し戻す。
PHPでは角度を扱う際に「度数法(degree)」ではなく「弧度法(radian)」を用いる必要があるため、deg2rad()関数を使用して変換を行う点がポイントです。

実装/解決策

回転処理を汎用的に利用するためには、関数化して引数で制御できるようにするのがベストプラクティスです。特に、回転方向(時計回り・反時計回り)や、結果を整数として扱うかどうかのフラグを持たせることで、実務上の柔軟性が高まります。以下のコードでは、回転行列の基本式に基づき、指定した角度分だけ座標をオフセットさせるロジックを実装しています。

サンプルプログラム

以下のコードは、指定した中心点から任意の座標を回転させ、結果を配列で返す関数です。そのままコピーしてテストにご活用ください。

  • 任意の座標を特定の中心軸で回転させる関数
  • @param float $x1 中心軸X
  • @param float $y1 中心軸Y
  • @param float $x2 回転させたい座標X
  • @param float $y2 回転させたい座標Y
  • @param float $angle 回転角度(度数)
  • @param bool $round 整数化するかどうか
  • @param bool $clockwise 時計回りならtrue
  • @return array 回転後の座標 [x, y]
  • /
    function point_rotate($x1, $y1, $x2, $y2, $angle, $round = false, $clockwise = false) {
    // 時計回りの場合は角度を反転
    if ($clockwise) $angle = -1 $angle;

    // 角度をラジアンに変換
    $rad = deg2rad($angle);

    // 相対座標の算出
    $dx = $x2 – $x1;
    $dy = $y2 – $y1;

    // 回転行列の計算
    $x = $dx cos($rad) – $dy sin($rad);
    $y = $dx sin($rad) + $dy cos($rad);

    // 中心座標を足し戻し、必要に応じて整数化して返却
    if ($round) {
    return [round($x1 + $x), round($y1 + $y)];
    } else {
    return [$x1 + $x, $y1 + $y];
    }
    }

    // 使用例:中心(50, 50)を軸に、(100, 100)を時計回りに30度回転
    $result = point_rotate(50, 50, 100, 100, 30, true, true);
    print_r($result);
    ?>

    応用・注意点

    実務でこの計算を用いる際の注意点は以下の通りです。
    1. 浮動小数点数の精度: 計算過程で非常に小さな誤差が生じることがあります。ピクセル単位の描画を行う際は、適宜round()やfloor()を用いて整数値に丸めることが重要です。
    2. 座標系の違い: コンピュータグラフィックスでは、通常「左上が(0,0)」となる座標系が一般的です。数学的な回転公式は「上がプラス」の座標系を前提としていることが多いため、画面描画に使う場合は、必要に応じてY座標の正負を考慮した調整を行ってください。
    3. パフォーマンス: 大量の座標を一度に計算する場合、ループ内で何度も三角関数を呼び出すと負荷が高まります。同じ角度で複数の点を回転させる場合は、先にcosとsinの結果を変数に保持しておくことで計算回数を減らす最適化が有効です。

    タイトルとURLをコピーしました