外部変形は データのやり取りをテキストファイルで行うので プログラム言語は 自由に選ぶことができます。図形は機能的かつシンプルなため、数多くのユーザーに受け入れられています。
jscriptで楕円弧の長さ(表示画面のスケール)を計測表示する
/* jscriptで楕円弧の長さ(表示画面のスケール)を計測表示する
@cls & echo off
copy jwc_temp.txt myfiles > nul
cscript //nologo //e:jscript %0 > jwc_temp.txt
goto:eof
REM #jww
REM #1ci 長さを計測する円・円弧を指示してください
REM #e
*/
function int(a){
return a < 0 ? Math.ceil(a) : Math.floor(a)
}
function apa(o, p){
return (90.0 * (2 * int( (o + 1) / 2) - 1) - p) * Math.pow(-1, o - 1)
}
function E2(p, k){ //第2種楕円積分(無限級数解)
var n, e, a, s_n, c, s, j
if (k == "" || k == null) {
k = p
p = Math.PI / 2
}
//if (k < 0 || 1 < k) { WScript.Echo("h#e()計算できませんでした\n"); return 0 }
if (k > 1-1e-15) { return Math.sin(p) }
n = 2.0
e = 0.0
a = 1.0
s_n = p
c = Math.cos(p)
s = Math.sin(p)
j = 0
while (Math.abs(a * s_n) > 1e-20 || j < 30000) {
e += a * s_n
a *= (n - 3.0) / n * k * k
s_n = ( (n - 1.0) * s_n - Math.pow(s, n - 1.0) * c) / n
n += 2
j += 1
}
return e
}
function arc_l(r, p1, p2, w){
var ek, lp, n1, n2, n3, k
with (Math) {
ek = E2(PI / 2, k = sqrt(1.0 - w * w))
if (p1 == p2) p2 += 360;
while (p1 < 0) p1 += 360;
while (p1 >= 360) p1 -= 360;
while (p2 < 0) p2 += 360;
while (p2 >= 360) p2 -= 360;
if (p1 == p2) {
lp = 4.0 * ek
} else {
lp = int(abs(p2 - p1) / 360.0) * 4.0 * ek
n1 = 1 + int(p1 / 90.0)
if (n1 > 4) n1 = 4;
lp += ek * ( (n1 + 1.0) % 2) + E2(apa(n1, p1) * PI / 180, k) * Math.pow(-1.0, n1 - 1)
n2 = 1 + int(p2 / 90.0)
if (n2 > 4) n2 = 4;
if (n1 == n2) n1 += 4;
n3 = 5 + 2 * int( (n2 - 1.0) / 2.0)
lp += ek * ( (n3 - n1) % 4) + E2(apa(n2, p2) * PI / 180, k) * Math.pow(-1.0, n2)
if (lp < 0.0) lp += 4.0 * ek;
if (lp > 4.0 * ek) lp -= 4.0 * ek;
}
}
return r * lp
}
function hex(x){
if (x == 10) return "a";
if (x == 11) return "b";
if (x == 12) return "c";
if (x == 13) return "d";
if (x == 14) return "e";
if (x == 15) return "f";
return x
}
hs = []
lg = ""
f = WScript.StdIn
while (! f.AtEndOfStream) {
F = ($_ = f.ReadLine()).split(/\s+/)
if (/^hs/i.test($_)) { //hs スケール
str = F.slice(1)
for (i in str) hs[hex(i)] = str[i] * 1.0;
}
if (/^lg[A-F0-9]/i.test($_)) { //lg レイヤグループ
plg = $_.substr(2, 1).toLowerCase(); if( lg == "" ) lg = plg;
}
if (/^ci/i.test($_)) { //ci 指示円
ci1 = F.slice(1)
p = hs[lg] / hs[plg]
for (i in ci1) ci1[i] *= 1.0;
ci1[2] *= p
if (ci1.length == 3) ci1 = ci1.concat(0, 360, 1, 0);
}
}
if (ci1[5] > 1-1e-15) {
p1 = ci1[3]
p2 = ci1[4]
p = p2 - p1
while (p <= 1e-15) p = p + 360;
while (p >= 360) p = p - 360;
lr = ci1[2] * p / 180.0 * Math.PI
} else {
lr = arc_l(ci1[2], ci1[3], ci1[4], ci1[5])
}
g = WScript.StdOut
g.WriteLine("h#円弧長 L = " + lr.toFixed(3))