SVGでインボリュート曲線を描く


アニメ『クロックワーク・プラネット』

歯車がぐりぐり動きます。歯車好きにはたまらないです。主人公は耳が良くて、4億以上ものパーツの音を聞き分けてしまいます。この能力ぞくぞくします。ストーリーの展開もいいし、都道府県がまるごとパージできる歯車ってところも壮大で面白い。エンディング曲もいいです。ところで最近歯車が出てくるアニメが多いですねえ。

歯車ということで、インボリュート曲線を描いてみます。

     1	use Math::Trig;
     2	
     3	$r=50;
     4	open(OUT,">/tmp/tmp.svg");
     5	print OUT<<EOL;
     6	<svg width="640" height="640">
     7	<rect x="0" y="0" width="640" height="640" fill="white"></rect>
     8	<circle cx="320" cy="320" r="$r" fill="none" stroke="red" />
     9	EOL
    10	
    11	for($t=0; $t<360;$t+=15){
    12		$rad=$t*pi/180;
    13		$x=320 + cos($rad)*$r ;
    14		$y=320 - sin($rad)*$r ;
    15		printf OUT '<line x1="320" y1="320" x2="%d" y2="%d" stroke="black"/>',$x,$y;
    16		print OUT "\n";
    17	
    18		$ix=$r;
    19		$iy=-($t*pi*2.0*$r/360.0);
    20		$x2 = 320 + (cos($rad)*$ix -sin($rad)*$iy);
    21		$y2 = 320 - (sin($rad)*$ix + cos($rad)*$iy);
    22		printf OUT '<line x1="%d" y1="%d" x2="%d" y2="%d" stroke="black"/>',$x,$y,$x2,$y2;
    23		print OUT "\n";
    24	
    25	}
    26	
    27	print OUT "</svg>";
    28	print OUT "\n";
    29	$cmd="inkscape -z -e out.png /tmp/tmp.svg";
    30	system($cmd);

この糸の先をつなげていけばインボリュート曲線となります。
少し改造するだけです。

     1	use Math::Trig;
     2	
     3	$r=50;
     4	open(OUT,">/tmp/tmp.svg");
     5	print OUT<<EOL;
     6	<svg width="640" height="640">
     7	<rect x="0" y="0" width="640" height="640" fill="white"></rect>
     8	<circle cx="320" cy="320" r="$r" fill="none" stroke="red" />
     9	EOL
    10	
    11	for($t=0; $t<360;$t+=1){
    12		$rad=$t*pi/180;
    13		$ix=$r;
    14		$iy=-($t*pi*2.0*$r/360.0);
    15		$x2 = 320 + (cos($rad)*$ix -sin($rad)*$iy);
    16		$y2 = 320 - (sin($rad)*$ix + cos($rad)*$iy);
    17		printf OUT '<circle cx="%d" cy="%d" r="2" fill="blue" />',$x2,$y2;
    18		print OUT "\n";
    19	
    20	}
    21	
    22	print OUT "</svg>";
    23	print OUT "\n";
    24	$cmd="inkscape -z -e out.png /tmp/tmp.svg";
    25	system($cmd);

できました。

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA