GUZAI3ノートブック

友人であるGUZAI3様の依頼で備忘録を書いています。

C言語で座標平面上の任意の点を反時計回りに回転させたときの座標を計算する

AtCoderで座標回転が出題されたときに苦労したので、ここで整理しておく。

まず、以下のように記号を定める。
(X, Y):回転前の座標
(X_{rotate}, Y_{rotate}):回転後の座標
\theta:反時計回りに回転させる角度

すると、原点を中心とした反時計回りの回転はこのように計算できる。


\left(
  \begin{array}{cc}
    X_{rotate} \\
    Y_{rotate} \\
  \end{array}
\right)

=

\left(
  \begin{array}{cc}
    \cos\theta & -\sin\theta \\
    \sin\theta & \cos\theta \\
\end{array}
  \right)

\left(
  \begin{array}{cc}
    X \\
    Y \\
  \end{array}
\right)

整理して...


\left(
  \begin{array}{cc}
    X_{rotate} \\
    Y_{rotate} \\
  \end{array}
\right)

=

\left(
  \begin{array}{cc}
    X \cos\theta - Y \sin\theta \\
    X \sin\theta + Y \cos\theta \\
\end{array}
  \right)


次に、原点ではなく任意の点を中心とした回転を考える。
上記に追加で、以下のように記号を定める。
(X_{center}, Y_{center}):中心の座標

最初に、中心の座標が原点になるように全ての座標を平行移動させる。
すると、原点を中心とした回転に帰着する。

あとは上記の計算に当てはめると...


\left(
  \begin{array}{cc}
    X_{rotate} - X_{center} \\
    Y_{rotate} - Y_{center} \\
  \end{array}
\right)

=

\left(
  \begin{array}{cc}
    \cos\theta & -\sin\theta \\
    \sin\theta & \cos\theta \\
\end{array}
  \right)

\left(
  \begin{array}{cc}
    X - X_{center} \\
    Y - X_{center} \\
  \end{array}
\right)

整理して...


\left(
  \begin{array}{cc}
    X_{rotate} \\
    Y_{rotate} \\
  \end{array}
\right)

=

\left(
  \begin{array}{cc}
    (X - X_{center}) \cos\theta - (Y - Y_{center}) \sin\theta + X_{center} \\
    (X - X_{center}) \sin\theta + (Y - Y_{center}) \cos\theta + Y_{center} \\
\end{array}
  \right)


C言語で計算プログラムを書いてみた。

#include <math.h>
#include <stdio.h>

int main() {
  double X, Y;    // Original coordinates
  double Xc, Yc;  // Center coordinates or rotation
  double Xr, Yr;  // Coordinates after rotation
  double angle;   // Angle of rotation (Radian)

  X = 5.0, Y = 3.0, Xc = 6.0, Yc = 3.5;  // Example of coordinates
  angle = 2.0 * acos(-1) / 6;            // Example of angle (60 deg)

  // Calculate rotation
  Xr = (X - Xc) * cos(angle) - (Y - Yc) * sin(angle) + Xc;
  Yr = (X - Xc) * sin(angle) + (Y - Yc) * cos(angle) + Yc;

  printf("Xr=%lf, Yr=%lf\n", Xr, Yr);  // Xr = 5.933, Yr = 2.384

  return 0;
}


本番で解きたかったけど解けなかった問題
D - Opposite