外部変形は データのやり取りをテキストファイルで行うので プログラム言語は 自由に選ぶことができます。図形は機能的かつシンプルなため、数多くのユーザーに受け入れられています。
mshtaで楕円弧の長さ(表示画面のスケール)を計測表示する
:mshtaで楕円弧の長さ(表示画面のスケール)を計測表示する
@echo off
if exist jwc_temp.txt (
copy jwc_temp.txt myfiles > nul
mshta %~f0 < myfiles > jwc_temp.txt
)
goto:eof
REM #jww
REM #1ci 長さを計測する円・円弧を指示してください
REM #bz
REM #e
<script>
/*
JScript による JW_CAD 外部変形
*/
//ユーザー定義関数
function int(a) { return a < 0 ? Math.ceil(a) : Math.floor(a) }
function sgn(x) { return x == 0 ? x : ( x > 0 ? 1 : -1 ) }
function fx(x, k) {
return Math.sqrt(1.0 - Math.pow(k * Math.sin(x), 2))
}
function apa(o, p) {
return (90.0 * (2 * int( (o + 1) / 2) - 1) - p) * Math.pow(-1, o - 1)
}
function eh(n, m, ee, hh) {
var pi = Math.PI
var i, j, e1, t, x0, pkm1, pk, t1, pkp1, pkm1
var den, d1, dpn, d2pn, d3pn, d4pn
var u, v, h, pp, dp, xi, fx, wi
e1 = n * (n + 1.0)
for (var i = 1; i <= m; i++) {
t = (4.0 * i - 1.0) * pi / (4.0 * n + 2.0)
x0 = (1.0 - (1.0 - 1.0 / n) / (8.0 * n * n)) * Math.cos(t)
pkm1= 1.0
pk = x0
for (var j = 2; j <= n; j++) {
t1 = x0 * pk
pkp1 = t1 - pkm1 - (t1 - pkm1) / j + t1
pkm1 = pk
pk = pkp1
}
den = 1.0 - x0 * x0
d1 = n * (pkm1 - x0 * pk)
dpn = d1 / den
d2pn = (2.0 * x0 * dpn - e1 * pk) / den
d3pn = (4.0 * x0 * d2pn + (2.0 - e1) * dpn) / den
d4pn = (6.0 * x0 * d3pn + (6.0 - e1) * d2pn) / den
u = pk / dpn
v = d2pn / dpn
h = -1.0 * u * (1.0 + 0.5 * u * (v + u * (v * v - d3pn / (3.0 * dpn))))
pp = pk + h * (dpn + 0.5 * h * (d2pn + h / 3.0 * (d3pn + 0.25 * h * d4pn)))
dp = dpn + h * (d2pn + 0.5 * h * (d3pn + h * d4pn / 3.0))
h -= pp / dp
xi = x0 + h
fx = d1 - h * e1 * (pk + 0.5 * h * (dpn + h / 3.0 * (d2pn + 0.25 * h * (d3pn + 0.2 * h * d4pn))))
wi = 2.0 * (1.0 - xi * xi) / (fx * fx)
ee[i] = xi
hh[i] = wi
}
}
function E2(p, k, n, m, ee, hh) {
if (k == 0 || n < 1) {
return p
}
var l = 0.0
for (var i = 1; i <= int(n / 2.0); i++) {
l += hh[i] * fx(ee[i] * p, k)
}
if( m == int(n / 2.0) + 1 ){ //奇数個の場合
l += hh[m] * fx(ee[m] * p, k) / 2.0
}
return l * p
}
function arc_l(rc, p1, p2, w) {
var pi = Math.PI
var p, lp, lr, lrp
p = p2 - p1
while (p <= 0 ) { p += 360 }
while (p > 360) { p -= 360 }
if (w == 1) {
lr = p * pi / 180.0 * rc
} else{
lrp = p * pi / 180.0 * rc
if (w > 1) {
w = 1.0 / w
rc = rc / w
p1 = p1 - 90.0
p2 = p2 - 90.0
}
var n = 150 //ガウス積分点の数 60~150 程度
var m = (n + n % 2) / 2
var k = Math.sqrt(1.0 - w * w)
var ee = new Array(1)
var hh = new Array(1)
eh(n, m, ee, hh)
var ek = E2(pi / 2.0, k, n, m, ee, hh)
// 弧長をガウス積分(第2種楕円積分)を利用して計算する
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 {
n1 = 1 + int(p1 / 90.0)
if (n1 > 4) n1 = 4;
lp = ek * ( (n1 + 1.0) % 2) + E2(apa(n1, p1) * pi / 180, k, n, m, ee, hh) * 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, n, m, ee, hh) * Math.pow(-1.0, n2)
if (lp < 0.0) lp += 4.0 * ek;
}
lr = lp * rc
}
return lr
}
function hex(x) { return x < 10 ? x : x.toString(16) }
hs =
hp =
ci = []
cin = 0
lg = ""
with (new ActiveXObject("Scripting.FileSystemObject")) {
f = GetStandardStream(0) //stdin
g = GetStandardStream(1) //stdout
while (! f.AtEndOfStream) {
F = ($_ = f.ReadLine()).split(/\s+/)
if (/^hk/i.test($_)) { //hk 軸角
hk = F[1]*1.0; continue
}
if (/^hs/i .test($_)) { //hs スケール
for (i = 0; i <= 15; i++) hs[hex(i)] = F[i + 1] * 1.0;
continue
}
if (/^hp[1-9][0-9]?/i .test($_)) { //hp 指示点
hp[ F[0].match(/[0-9]+/) ] = [ F[1] * 1.0, F[2] * 1.0 ]
continue
}
if (/^lg[A-F0-9]/i .test($_)) { //lg レイヤグループ
plg = $_.substr(2, 1).toLowerCase(); if (lg == "") lg = plg;
continue
}
if (/^hhp([1-9][0-9]?)ci/i .test($_)) { cin = RegExp.$1; continue }
if (/^ci/i .test($_)) { //ci 指示円
p = hs[lg]
// p = hs[lg] / hs[plg]
for (i = 1; i <= 3; i++) F[i] *= p;
ci[cin] = F.slice(1, F.length)
if (F.length == 4) {
ci[cin] = ci[cin].concat([0, 360, 1, hk])
}
}
}
f.close()
r = ci[1][2]
p1 = ci[1][3]
p2 = ci[1][4]
w = ci[1][5]
lr = arc_l(r, p1, p2, w)
g.WriteLine("h#円弧長 L = " + lr.toFixed(3))
}
close()
</script>
スクリプト言語は jscript を使用しています。楕円積分はガウス-ルジャンドルの方法によっています。積分点の係数は対称性を利用しています。