追記)座標を回転させる方法

ということで,昨日回転させる方法について関数を書いたのだけど,締切が終わってしばらくするとやっぱり「逆回転をオプションで指定するってださいな」と思い始めた。

ところに,ツイッターでメンションが。@masashikomoriさんのお知り合いのかた(@SogoHiroyukiさん)からatan2を使えば良いですよ,と教えてもらいました。具体的なやり方まで。
で,それを参考に(てか丸写しだわなw)昨日の関数を書き直した。かなりスッキリ。
っていうか,atan2関数って明らかに「これ」のために準備されてる関数だよなぁ。

ということで,修正後の関数。
今回のバージョンは,引数にまず元の座標セットを入れて(pre),その何行目(key)を,どういうベクトルに(targetVec)に合わせるか,という指定をします。ノルムの調節がしたかったら,オプションのnorm.adjをTRUEにしてあげる。
ターゲットベクトルを入れるようにしたのは,目標の座標がセットではなくてベクトルに過ぎないので,それなら例えばc(1,0)みたいなもんに基準化したら良いじゃない,と思い至ったからです。

rotateConfig <span class="synStatement">&lt;-</span> <span class="synType">function</span><span class="synSpecial">(</span>pre<span class="synSpecial">,</span>key<span class="synSpecial">,</span>targetVec<span class="synSpecial">,</span>norm.adj=<span class="synConstant">FALSE</span><span class="synSpecial">){</span>
prePoint <span class="synStatement">&lt;-</span> pre<span class="synSpecial">[</span>key<span class="synSpecial">,]</span>
postPoint <span class="synStatement">&lt;-</span> targetVec
qa <span class="synStatement">&lt;-</span> atan2<span class="synSpecial">(</span>prePoint<span class="synSpecial">[</span><span class="synConstant">1</span><span class="synSpecial">],</span>prePoint<span class="synSpecial">[</span><span class="synConstant">2</span><span class="synSpecial">])</span>
qb <span class="synStatement">&lt;-</span> atan2<span class="synSpecial">(</span>targetVec<span class="synSpecial">[</span><span class="synConstant">1</span><span class="synSpecial">],</span>targetVec<span class="synSpecial">[</span><span class="synConstant">2</span><span class="synSpecial">])</span>
rot = qb - qa
<span class="synComment">#回転行列</span>
rotmat <span class="synStatement">&lt;-</span> <span class="synType">matrix</span><span class="synSpecial">(</span>c<span class="synSpecial">(</span>cos<span class="synSpecial">(</span>rot<span class="synSpecial">),</span>-sin<span class="synSpecial">(</span>rot<span class="synSpecial">),</span>sin<span class="synSpecial">(</span>rot<span class="synSpecial">),</span>cos<span class="synSpecial">(</span>rot<span class="synSpecial">)),</span> <span class="synConstant">2</span><span class="synSpecial">,</span> <span class="synConstant">2</span><span class="synSpecial">)</span>
<span class="synComment"># xyの回転後座標</span>
a_rotated <span class="synStatement">&lt;-</span> rotmat %*% t<span class="synSpecial">(</span>pre<span class="synSpecial">)</span>
<span class="synComment">#回転後のノルムをそろえる(オプション)</span>
<span class="synStatement">if</span><span class="synSpecial">(</span> norm.adj==<span class="synConstant">TRUE</span><span class="synSpecial">){</span>
ret <span class="synStatement">&lt;-</span>a_rotated * <span class="synSpecial">(</span>sqrt<span class="synSpecial">((</span>t<span class="synSpecial">(</span>postPoint<span class="synSpecial">)</span> %*% postPoint<span class="synSpecial">))</span>/sqrt<span class="synSpecial">((</span>t<span class="synSpecial">(</span>prePoint<span class="synSpecial">)</span> %*% prePoint<span class="synSpecial">)))[</span><span class="synConstant">1</span><span class="synSpecial">,</span><span class="synConstant">1</span><span class="synSpecial">]</span>
<span class="synSpecial">}</span><span class="synStatement">else</span><span class="synSpecial">{</span>
ret <span class="synStatement">&lt;-</span> a_rotated
<span class="synSpecial">}</span>
<span class="synStatement">return</span><span class="synSpecial">(</span>t<span class="synSpecial">(</span>ret<span class="synSpecial">))</span>
<span class="synSpecial">}</span>

はー,楽しかった。

以下余談。

思い起こせば高校生の時、三角関数が苦手だった。だから理系に進めなかったんだな。あと物理が駄目だったなw
あの時先生が「将来お前らもMDSの布置を回転したくなることがあると思うが…」って言うといてくれたらもっと勉強に身が入ったのに。
まぁ習う時はどのシーンで使うかなんかイメージできないわけで,学ぶときはいつかどこかで役立ててやる,というモチベーションを持っておくことが大事なんだな,と思った。そうでなければ,なんで覚えなあかんねん,意味わからん・・・の蓄積にしかならないからなぁ。

未だに学部生時代にとった講義ノートに助けられているのは,俺のこういう貧乏人根性(?)にあったのだなぁ,と思う。
こればっかりは教育してやれるところじゃないよねぇ。