直交座標(xy座標)点の回転

ようするにこういう。。。

(x, y)の点をdだけ回転させた(x', y')をもとめる。頻出なんだけど、どうも関数化してなかったのを関数作った記念。いや、なんか昔に書いたネタのような気もするし、普通のひとはクォータニヨンとか使って回転させるのかもしれんね。。。



まあ、こんな感じに考える。P(x,y)をdだけ回転させたP'(x',y')を求める。この時、Pとx座標の角度はθとする。あ、図に描き忘れたけど、原点oからPまでの長さをLとでもしましょう。この時、直交座標を極座標に変換する要領で

  /* I. */
  x = L * cos(θ);
  y = L * sin(θ);

という関係になる。これも頻出ですよ〜。
(x', y')も。こんとき、P'とx座標のなす角はθ+dですね。

  /* II. */
  x' = L * cos(θ+d);
  y' = L * sin(θ+d);

ところで、高校ぐらいでやった三角関数の加法定理ってのがあって、

  /* III. */
  cos(θ+d) = cos(θ) * cos(d) - sin(θ) * sin(d);
  sin(θ+d) = sin(θ) * cos(d) + cos(θ) * sin(d);

というのが成り立つ。こいつをII.式に代入すると、

  /* IV. */
  x' = L * cos(θ+d) = L * cos(θ) * cos(d) - L * sin(θ) * sin(d);
  y' = L * sin(θ+d) = L * sin(θ) * cos(d) + L * cos(θ) * sin(d);

ところで、x = L * cos(θ), y = L * sin(θ)でしたね、ってことで

  /* V. */
  x' = x * cos(d) - y * sin(d);
  y' = y * cos(d) + x * sin(d);

が求まりました。パチパチ!

ソースで書いても全然むつかしくないね!

  POINT* RotatePoint(POINT* io, double Angle)
  {
    double SinA = sin(Angle);
    double cosA = cos(Angle);
    int x = io->x;
    int y = io->y;

    io->x = x * CosA - y * SinA;
    io->y = x * SinA + y * CosA;

    return io;
}

こんな感じか。全然むつかしくないんだけど、毎回引くんだか足すんだか判らなくなって、そのたびに加法定理を思い出すのがダルかったんだよね〜。