外部変形は データのやり取りをテキストファイルで行うので プログラム言語は 自由に選ぶことができます。図形は機能的かつシンプルなため、数多くのユーザーに受け入れられています。
perlで楕円弧の長さ(表示画面のスケール)を計測表示する
:perlで楕円弧の長さ(表示画面のスケール)を計測表示する
@echo off
perl -x %~f0 jwc_temp.txt
goto:eof
REM #jww
REM #1ci 長さを計測する円・円弧を指示してください
REM #bz
REM #e
#!perl -i.bak
## a2p.exe 024arc_l-2.awk で 変換後に修正した。
BEGIN {
$PI = atan2(1, 1) * 4;
}
while (<>) {
chomp; # strip record separator
@Fld = split(' ', $_, -1);
if (/^hs/) {
for ($i = 0; $i <= 15; $i++) {
$hs{sprintf('%x', $i)} = $Fld[$i + 1];
}
}
if (/^lg[0-9a-f]/) {
$plg = substr($_, 2, 1);
if ($lg eq '') { $lg = $plg; }
}
if (/^ci/) {
$lr = cilength(@Fld) * $hs{$lg}; # / $hs{$plg};
printf "h#円弧長 L = %.03f\n", $lr;
}
}
sub cilength {
my ($r, $p1, $p2, $w, $l);
$r = $_[3];
if (@_ == 4) {
($p1, $p2, $w) = (0, 0, 1);
} elsif (@_ == 8) {
($p1, $p2, $w) = @_[4..6];
if ($w > 1) {
$w = 1 / $w;
$r /= $w;
$p1 -= 90;
$p2 -= 90;
}
}
if ($w == 1) {
$l = ($p1 == $p2 ? 360 : $p2 - $p1) * $PI / 180;
} else {
&eh($N = int(12 * (1.5 / $w))); #Gauss-Legendre
$l = &arc_l(sqrt(1 - $w ** 2), $p1, $p2);
}
return $l * $r;
}
sub arc_l {
local($k, $p1, $p2, $lp, $n1, $n2, $n3) = @_;
$Ek = &E($k, $PI / 2);
if ($p1 == $p2) { return 4 * $Ek; }
$n1 = int($p1 / 90) + 1;
if ($n1 > 4) { $n1 = 4; }
$lp = $Ek * ( ($n1 + 1) % 2) + &E($k, &apa($n1,$p1) * $PI / 180) * (-1) ** ($n1 - 1);
$n2 = int($p2 / 90) + 1;
if ($n2 > 4) { $n2 = 4; }
if ($n1 == $n2) { $n1 += 4; }
$n3 = 2 * int( ($n2 - 1) / 2) + 5;
$lp += $Ek * ( ($n3 - $n1) % 4) + &E($k, &apa($n2,$p2) * $PI / 180) * (-1) ** $n2;
if ($lp < 0) { $lp += 4 * $Ek; }
$lp;
}
sub apa {
local($o, $p) = @_;
(90 * (int( ($o + 1) / 2) * 2 - 1) - $p) * (-1) ** ($o - 1);
}
sub f {
local($X, $k) = @_;
sqrt(1 - ($k * sin($X)) ** 2);
}
sub E { #Gauss-Legendre
local($k, $p, $i, $l) = @_;
$l = 0;
if ($N > 1) {
for ($i = 1; $i <= int($N / 2); $i++) {
$l += $h{$i} * &f($e{$i} * $p, $k);
}
}
if ($N % 2 == 1) {
my $M = int($N / 2) + 1;
$l += $h{$M} * &f($e{$M} * $p, $k) / 2;
}
$l * $p;
}
sub eh { #Gauss-Legendre 積分点の係数
my ($N) = @_;
my ($M, $E1, $PAI);
my ($I, $T, $X0, $PKM1, $PK, $K, $T1, $PKP1);
my ($DEN, $D1, $DPN, $D2PN, $D3PN, $D4PN, $U, $V, $H, $P, $DP, $XI, $FX, $WI);
$M = int($N / 2) + $N % 2;
$E1 = $N * ($N + 1);
$PAI = atan2(1, 1) * 4;
for ($I = 1; $I <= $M; $I++) {
#DO 1
$T = (4 * $I - 1) * $PAI / (4 * $N + 2);
$X0 = (1 - (1 - 1 / $N) / (8 * $N * $N)) * cos($T);
$PKM1 = 1;
$PK = $X0;
for ($K = 2; $K <= $N; $K++) {
#DO 3
$T1 = $X0 * $PK;
$PKP1 = $T1 - $PKM1 - ($T1 - $PKM1) / $K + $T1;
$PKM1 = $PK;
$PK = $PKP1;
} # 3
$DEN = 1 - $X0 * $X0;
$D1 = $N * ($PKM1 - $X0 * $PK);
$DPN = $D1 / $DEN;
$D2PN = (2 * $X0 * $DPN - $E1 * $PK) / $DEN;
$D3PN = (4 * $X0 * $D2PN + (2 - $E1) * $DPN) / $DEN;
$D4PN = (6 * $X0 * $D3PN + (6 - $E1) * $D2PN) / $DEN;
$U = $PK / $DPN;
$V = $D2PN / $DPN;
$H = -$U * (1 + .5 * $U * ($V + $U * ($V * $V - $D3PN / (3 * $DPN))));
$P = $PK + $H * ($DPN + .5 * $H * ($D2PN + $H / 3 * ($D3PN + .25 * $H * $D4PN)));
$DP = $DPN + $H * ($D2PN + .5 * $H * ($D3PN + $H * $D4PN / 3));
$H = $H - $P / $DP;
$XI = -($X0 + $H);
$FX = $D1 - $H * $E1 * ($PK + .5 * $H * ($DPN + $H / 3 * ($D2PN + .25 * $H * ($D3PN + .2 * $H * $D4PN))));
$WI = 2 * (1 - $XI * $XI) / ($FX * $FX);
$e{$I} = $XI;
$h{$I} = $WI;
} # 1
}
__END__