任意の座標を原点から指定した角度回す

x軸とy軸からなる直交座標(「[デカルト座標系](https://ja.wikipedia.org/wiki/%E7%9B%B4%E4%BA%A4%E5%BA%A7%E6%A8%99%E7%B3%BB)」)における任意の点$(x, y)$を、原点$(0, 0)$から角度$\theta$回した座標$(x', y')$はつぎの式で求められます。

```math
x' =  x\cos\theta - y\sin\theta\\
y' =  x\sin\theta + y\cos\theta
```

結論は以上です。本稿はこの式について、数学のいくつかの分野から異なる切り口で考えてみます。

#三角関数のsinとcosの定義
まず、三角関数の$\sin$と$\cos$です。つぎのように定義されます。

> 半径1の円(「[単位円](https://ja.wikipedia.org/wiki/%E5%8D%98%E4%BD%8D%E5%86%86)」)の円周上の点$(x, y)$がx軸の正方向と角度$\theta$をなすとき、その座標は$(\cos\theta, \sin\theta)$で表されます。

####図001▪️三角関数のsinとcos
![図001](https://qiita-image-store.s3.amazonaws.com/0/128949/8bdaad21-321b-9a8d-3914-8b4f5b2ee7f3.png)


高校の数学で、三角関数は直角三角形の辺の比([三角比](https://www.irohabook.com/sankakuhi))で習ったという方も多いでしょう。それはもう忘れてください。

平面上の座標は、$(x, y)$のほかにも表し方があります。たとえば、レーダーでは距離と角度で位置を示します(これを「極座標」といいます)。北東$1km$の座標を$(x, y)$で表したらどうなるでしょう。$(\cos45°, \sin45°)$(単位$km$)ですね。

つまり、三角関数の$\sin$と$\cos$は、レーダーの極座標を$(x, y)$座標に換える関数なのです。原点からの距離を$r$、角度が$\theta$とすれば、座標はただちに$(r\cos\theta, r\sin\theta)$で表せます。それが具体的にどういう数値になるかという計算はコンピュータに任せればよいことです。

#座標を原点から指定した角度回す
つぎに、座標$(x, y) = (r\cos\theta, r\sin\theta)$をさらに原点から角度$\omega$(オメガ)回しましょう。原点からの距離は、三平方の定理から$r = \sqrt{x^2 + y^2}$です。この長さは変えません。すると、回転したあとの座標は、$(x', y') = (r\cos(\theta + \omega), r\sin(\theta + \omega))$となります。

もちろん、計算はコンピュータに任せます。とはいえ、平面上のたくさんの点をすべて、原点から同じ角度($\omega$)回す場合、計算の負荷が上がりそうです。原点からの距離($r$)も角度($\theta$)も点ごとに違います。`for`ループの中で、距離($r$)を三平方の定理、角度($\theta$)は`Math.atan2()`メソッドで調べたうえで、`Math.cos()`と`Math.sin()`により計算しなければならないのです。

改めて、はじめに示した式をご覧ください。回す角度($\omega$)が一定なら、$cos$と$sin$の値は`for`ループの外で変数に入れてしまえます。そして、それぞれの点の$(x, y)$座標の値にもとづいて計算しますから、原点からの距離も求めずに済むのです。

#ベクトルと行列
平面上の座標は、ベクトルと捉えることもできます。その座標$(x, y)$を原点から角度$\theta$回す場合には、つぎのような[回転行列](https://ja.wikipedia.org/wiki/%E5%9B%9E%E8%BB%A2%E8%A1%8C%E5%88%97#2.E6.AC.A1.E5.85.83.E3.81.AE.E5.9B.9E.E8.BB.A2.E8.A1.8C.E5.88.97)を座標ベクトルに(左から)乗じます。

```math
\begin{pmatrix}
\cos\theta & -\sin\theta\\
\sin\theta & \cos\theta 
\end{pmatrix}
\begin{pmatrix}
x\\
y 
\end{pmatrix}\\
=
\begin{pmatrix}
x\cos\theta - y\sin\theta\\
x\sin\theta + y\cos\theta 
\end{pmatrix}
```

ここではベクトルや行列、それらの演算について知らなくて構いません。計算結果は、はじめに示した式と同じですから。

#複素数
今度は、複素数です。実数と虚数の和で表されます($a + bi$)。[虚数単位](https://ja.wikipedia.org/wiki/%E8%99%9A%E6%95%B0%E5%8D%98%E4%BD%8D)$i$は、2乗すると$i^2 = -1$になるという摩訶不思議な性質をもちます。[2次方程式の解](https://ja.wikipedia.org/wiki/%E4%BA%8C%E6%AC%A1%E6%96%B9%E7%A8%8B%E5%BC%8F#.E4.BA.8C.E6.AC.A1.E6.96.B9.E7.A8.8B.E5.BC.8F.E3.81.AE.E6.A0.B9)に表れました。

実数は[数直線上](https://ja.wikipedia.org/wiki/%E7%9B%B4%E7%B7%9A#.E5.BA.A7.E6.A8.99)の点で表せます。実数の数直線を水平軸(実軸)としたとき、虚数の数直線を原点0で直行する垂直軸(虚軸)とすると、任意の複素数はこの直交座標上の点として示されます。これを「[複素平面](https://ja.wikipedia.org/wiki/%E8%A4%87%E7%B4%A0%E5%B9%B3%E9%9D%A2)」と呼びます。

####図002▪️複素平面
![図002](https://qiita-image-store.s3.amazonaws.com/0/128949/3d9cd041-3add-613d-9a0a-42aa926097a4.png)

複素平面でも三角関数の$sin$と$cos$は同じように使えます。つまり、単位円上にある複素数は、実軸の正方向となす角度が$\theta$なら$\cos\theta + i\sin\theta$と表せるのです。

###図003▪️単位円上の複素数
![図003](https://qiita-image-store.s3.amazonaws.com/0/128949/4b5c620f-9c8e-8f33-33ff-86ddbeb81fbe.png)

ふたつの複素数$\alpha$と$\beta$の乗算を考えましょう。積の複素数$\alpha\beta$は、原点からの距離$|\alpha\beta|$がそれぞれの絶対値を掛け合わせた$|\alpha||\beta|$になります。これは実数と同じです。つぎに実軸となす角度が$\alpha$は$\theta$、$\beta$が$\omega$だったとき、積$\alpha\beta$の角度はふたつの和$\theta + \omega$となることが、[複素平面の研究](https://ja.wikipedia.org/wiki/%E8%A4%87%E7%B4%A0%E5%B9%B3%E9%9D%A2#.E8.A4.87.E7.B4.A0.E6.95.B0.E3.81.AE.E7.A9.8D.E3.81.A8.E5.9B.9E.E8.BB.A2)からわかりました。

ここで、任意の複素数$z = x + iy$を原点から角度$\theta$回してみましょう。原点からの距離は変えないのですから、絶対値が1で角度$\theta$の複素数、つまり$\cos\theta + i\sin\theta$を掛け合わせればよいのです。

```math
(x + iy)(\cos\theta + i\sin\theta)\\
= (x\cos\theta - y\sin\theta) + i(x\sin\theta + y\cos\theta)
```

求められた複素数をxy直交座標で表せば、$(x\cos\theta - y\sin\theta, x\sin\theta + y\cos\theta)$となって、やはりはじめに示した式と同じになります。

#座標回転の式を使った作例
座標回転の式を使った作例もひとつご紹介しておきましょう。JavaScriptライブラリのCreateJSでつくった「[EaselJSのMatrix2Dクラスを用いた3次元表現](http://jsdo.it/FumioNonaka/6VOP)」です。マウスポインタの位置に応じて、3次元空間で立方体が回ります。

####図004▪️3次元で立方体をマウスポインタに合わせて回す
![03_02_013.png](https://qiita-image-store.s3.amazonaws.com/0/128949/b3c4bf55-9643-84ca-e030-9f6f83754ba5.png)
[\>\> jsdo.itへ](http://jsdo.it/FumioNonaka/6VOP)

つぎのようなJavaScriptの関数で、立方体の頂点を回しています。`Point`は、xy座標をプロパティに備えたCreateJSのオブジェクトです。3次元なのにxy座標だけで回せるのかと疑問に思われるかもしれません。3次元の回転は、xy平面、yz平面、zx平面の3つに分けて座標を計算すればよいので、2次元平面における回転の組み合わせになるのです。

```js
function rotatePoint2D(nRadians, nX, nY) {
	var nSin = Math.sin(nRadians);
	var nCos = Math.cos(nRadians);
	var point2D = new createjs.Point();
	point2D.x = nCos * nX - nSin * nY;
	point2D.y = nSin * nX + nCos * nY;
	return point2D;
}
```