#!/usr/local/bin/perl
#
# usage: prel Involute_of_circle.pl

use strict;
use diagnostics;
use Math::Trig;#三角関数を使うモジュール



#--パラメータ
my $Radius = 20;#円の半径(パラメータ)
my $Theta = 0;#媒介変数
my $EndAngle = 4 * pi();#巻きつける量
my $Interval = 360;#描画の細かさ
my $PlotWidth = 250;#軸を表示する範囲
my $InvoluteLineWidth = 3;#Involuteの線の太さ
my $OtherLineWidth = 2;#その他の線の太さ
my $OriginX = 300;#描画の原点を取る位置(X座標)
my $OriginY = 300;#描画の原点を取る位置(Y座標)
my $AnimationTime = 20;#アニメーションにかかる時間



my @X = ($OriginX + $Radius);
my @Y = ($OriginY);
my @ContactX = ($OriginX + $Radius);
my @ContactY = ($OriginY);
my $i;



open(PS,">Involute_of_circle.ps");#PostScriptによるファイル出力
open(SVG,">Involute_of_circle.svg");#SVGによるファイル出力

print PS "%!PS-Adobe-3.0
%%BoundingBox: 0 0 ", $OriginX * 2 ," ", $OriginY * 2 ,"
	newpath %x軸
	$OtherLineWidth setlinewidth
	", $OriginX - $PlotWidth ," $OriginY moveto
	", $OriginX + $PlotWidth ," $OriginY lineto
	0.5 0.5 0.5 setrgbcolor
	stroke
	newpath %y軸
	$OtherLineWidth setlinewidth
	$OriginX ", $OriginY - $PlotWidth ," moveto
	$OriginX ", $OriginY + $PlotWidth ," lineto
	0.5 0.5 0.5 setrgbcolor
	stroke
	newpath %円
	0.5 0.5 0.5 setrgbcolor
	$OtherLineWidth setlinewidth
	$OriginX $OriginY $Radius 0 360 arc
	stroke
";
print SVG "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
	<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">
	<svg width=\"", $OriginX * 2 ,"\" height=\"", $OriginY * 2 ,"\" xmlns=\"http://www.w3.org/2000/svg\">
	<line x1=\"", $OriginX - $PlotWidth ,"\" y1=\"$OriginY\" x2=\"", $OriginX + $PlotWidth ,"\" y2=\"$OriginY\" style=\"stroke:#cccccc; stroke-width:$OtherLineWidth\"/>
	<line x1=\"$OriginX\" y1=\"", $OriginY - $PlotWidth ,"\" x2=\"$OriginX\" y2=\"", $OriginY + $PlotWidth ,"\" style=\"stroke:#cccccc; stroke-width:$OtherLineWidth\"/>
	stroke
	<circle cx=\"$OriginX\" cy=\"$OriginY\" r=\"$Radius\" style=\"stroke:#000000; stroke-width:$OtherLineWidth; fill: none\" >
	</circle>
";


#--奇跡の計算
for($Theta=0 ; $Theta<=$EndAngle + pi()/$Interval; $Theta+=2*pi()/$Interval){
	push (@ContactX, $OriginX + $Radius * cos($Theta));
	push (@ContactY, $OriginY + $Radius * sin($Theta));
	push (@X, $OriginX + $Radius * (cos($Theta) + $Theta * sin($Theta)));
	push (@Y, $OriginY + $Radius * (sin($Theta) - $Theta * cos($Theta)));
}



#--インボリュートの描画
print PS "
	newpath
	1 0 0 setrgbcolor
	$InvoluteLineWidth setlinewidth
	$X[0] $Y[0] moveto
	";
	print SVG "<polyline points=\"$X[0] ", $OriginX * 2 - $Y[0];
for($i=1 ; $i<$#X ; $i++){
	print PS "$X[$i] $Y[$i] lineto\n";
	print SVG ", $X[$i] ", $OriginX * 2 - $Y[$i];
}
print PS "stroke\n";
print SVG "\" style=\"stroke:#ff0000; stroke-width:$InvoluteLineWidth; fill: none\"/>\n";



#--巻きついた糸の描画
print SVG "<line x1=\"$ContactX[0]\" y1=\"$ContactY[0]\" x2=\"$X[0]\" y2=\"$Y[0]\" style=\"stroke:#000000; stroke-width:$OtherLineWidth\">";
print SVG "<animate attributeType=\"XML\" attributeName=\"x1\" begin=\"0\" dur=\"$AnimationTime\" values=\"$X[0]";
for($i=1 ; $i<$#X ; $i++){
	print SVG ";$ContactX[$i]";
}
print SVG "\" repeatCount=\"indefinite\"/>\n";
print SVG "<animate attributeType=\"XML\" attributeName=\"y1\" begin=\"0\" dur=\"$AnimationTime\" values=\"$Y[0]";
for($i=1 ; $i<$#X ; $i++){
	print SVG ";", $OriginY * 2 - $ContactY[$i];
}
print SVG "\" repeatCount=\"indefinite\"/>\n";
print SVG "<animate attributeType=\"XML\" attributeName=\"x2\" begin=\"0\" dur=\"$AnimationTime\" values=\"$X[0]";
for($i=1 ; $i<$#X ; $i++){
	print SVG ";$X[$i]";
}
print SVG "\" repeatCount=\"indefinite\"/>\n";
print SVG "<animate attributeType=\"XML\" attributeName=\"y2\" begin=\"0\" dur=\"$AnimationTime\" values=\"$Y[0]";
for($i=1 ; $i<$#X ; $i++){
	print SVG ";", $OriginY * 2 - $Y[$i];
}
print SVG "\" repeatCount=\"indefinite\"/>\n";
print SVG "</line>";


#--インボリュート上の点の描画
print SVG "<circle cx=\"$X[0]\" cy=\"$Y[0]\" r=\"", $InvoluteLineWidth * 1.5 ,"\" style=\"stroke:none; stroke-width:$OtherLineWidth; fill: #000000\" >";
print SVG "<animate attributeType=\"XML\" attributeName=\"cx\" begin=\"0\" dur=\"$AnimationTime\" values=\"$X[0]";
for($i=1 ; $i<$#X ; $i++){
	print SVG ";$X[$i]";
}
print SVG "\" repeatCount=\"indefinite\"/>\n";
print SVG "<animate attributeType=\"XML\" attributeName=\"cy\" begin=\"0\" dur=\"$AnimationTime\" values=\"$Y[0]";
for($i=1 ; $i<$#X ; $i++){
	print SVG ";", $OriginY * 2 - $Y[$i];
}
print SVG "\" repeatCount=\"indefinite\"/>\n";
print SVG "</circle>";




print PS "
	showpage
";
print SVG "
	</svg>
";

close(SVG);
close(PS);

