ということで,昨日回転させる方法について関数を書いたのだけど,締切が終わってしばらくするとやっぱり「逆回転をオプションで指定するってださいな」と思い始めた。
ところに,ツイッターでメンションが。@masashikomoriさんのお知り合いのかた(@SogoHiroyukiさん)からatan2を使えば良いですよ,と教えてもらいました。具体的なやり方まで。
で,それを参考に(てか丸写しだわなw)昨日の関数を書き直した。かなりスッキリ。
っていうか,atan2関数って明らかに「これ」のために準備されてる関数だよなぁ。
ということで,修正後の関数。
今回のバージョンは,引数にまず元の座標セットを入れて(pre),その何行目(key)を,どういうベクトルに(targetVec)に合わせるか,という指定をします。ノルムの調節がしたかったら,オプションのnorm.adjをTRUEにしてあげる。
ターゲットベクトルを入れるようにしたのは,目標の座標がセットではなくてベクトルに過ぎないので,それなら例えばc(1,0)みたいなもんに基準化したら良いじゃない,と思い至ったからです。
rotateConfig <span class="synStatement"><-</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"><-</span> pre<span class="synSpecial">[</span>key<span class="synSpecial">,]</span> postPoint <span class="synStatement"><-</span> targetVec qa <span class="synStatement"><-</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"><-</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"><-</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"><-</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"><-</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"><-</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の布置を回転したくなることがあると思うが…」って言うといてくれたらもっと勉強に身が入ったのに。
まぁ習う時はどのシーンで使うかなんかイメージできないわけで,学ぶときはいつかどこかで役立ててやる,というモチベーションを持っておくことが大事なんだな,と思った。そうでなければ,なんで覚えなあかんねん,意味わからん・・・の蓄積にしかならないからなぁ。
未だに学部生時代にとった講義ノートに助けられているのは,俺のこういう貧乏人根性(?)にあったのだなぁ,と思う。
こればっかりは教育してやれるところじゃないよねぇ。