2012年4月16日月曜日

Asymptoteでバネを描く

Asymptoteで2次元のバネを描いてみます。
まず螺旋$\ell$を$\ell(t)=(a\cos t, a\sin t, t)$と定義し、$\ell$を$y$軸周りに回転したものを$z$軸の正の側から眺める($x$-$y$平面に射影する)と、バネに見えるはずです。
$y$軸周りを$z$軸を$x$軸に向ける向きに角度$\theta$だけ回転する回転行列は
\[
R_y(\theta)
=\begin{pmatrix}\cos \theta & 0 &\sin \theta \\0 & 1 & 0\\-\sin \theta & 0 & \cos \theta\end{pmatrix}
\]
で与えられるので、$\ell(t)$を$R_y(\theta)$で回転させると
\[
\begin{pmatrix}
x \\ y\\ z
\end{pmatrix}
= \begin{pmatrix}\cos \theta & 0 &\sin \theta \\0 & 1 & 0\\-\sin \theta & 0 & \cos \theta\end{pmatrix}
\begin{pmatrix}
 a\cos t \\ b\sin t \\ t
\end{pmatrix}
=
\begin{pmatrix}
a\cos \theta \cos  t + t\sin \theta \\
a\sin t \\ -a\sin\theta \cos t + t \cos \theta
\end{pmatrix}
\]
となります。したがってこの螺旋を$x$-$y$平面に射影したものは
\[
\begin{pmatrix}
x \\ y
\end{pmatrix}
=
\begin{pmatrix}
a\cos \theta \cos  t + t\sin \theta \\
a\sin t
\end{pmatrix}\]
です。これをAsymptoteで描画してみたのが次の図です。


size(10cm);

import graph;
real a=10; // 螺旋の半径
real b=70pi/180; // y軸周りの回転角度
real c=7;

//螺旋 l(t)=(a\cos t, a\sin t, t)をy軸周りに角b回転させたものをx-y平面に射影した図形
pair l(real t) {return (a*(cos(b))*cos(t)+t*sin(b),a*sin(t));};
draw(graph(l,-(2c-1)*pi,(2c)*pi,400,operator ..));


ここでは、400個の点をベジエ曲線で補間したグラフを描いています。200個よりも少ないと歪みが顕著に見えるようになりました。点の数を指定しないと、定義域を広げるほど歪みが激しくなっていきます。
以前にinkscapeでのバネの描き方を紹介しましたが、inkscapeでも数学関数が使えるので同様の方法でバネを描くことが出来ます。バネを伸ばしたり縮めたりするのはinkscapeのほうが楽ですね。