外部変形は データのやり取りをテキストファイルで行うので プログラム言語は 自由に選ぶことができます。図形は機能的かつシンプルなため、数多くのユーザーに受け入れられています。
luaで楕円弧の長さ(表示画面のスケール)を計測表示する
:luaで楕円弧の長さ(表示画面のスケール)を計測表示する
@echo off
for /f "delims=:" %%n in ('findstr /n "^#!" %0') do (
copy jwc_temp.txt myfiles > nul
more +%%n %0 | lua > jwc_temp.txt
)
goto:eof
REM #jww
REM #1ci 長さを計測する円・円弧を指示してください
REM #bz
REM #e
#!この次の行からプログラムを書いてください
function sprintf(...)
if #{...} == 0 then return end
if #{...} == 1 then return ... end
return string.format(...)
end
function printf(...)
return print(sprintf(...))
end
function int(a) return a < 0 and math.ceil(a) or math.floor(a) end
function apa(o, p)
return (90 * (int( (o + 1) / 2) * 2 - 1) - p) * (-1) ^ (o - 1)
end
function fx(x, k)
return math.sqrt(1 - (k * math.sin(x)) ^ 2)
end
function arc_l(r, p1, p2, w)
local k, Ek, lp, n1, n2, n3
--r 半径
--p1 始角 ゚
--p2 終角 ゚
--w 扁平率
--k 離心率
--Ek 第二種完全楕円積分の値
if w > 1 then
w = 1 / w
r = r / w
p1 = p1 - 90
p2 = p2 - 90
end
k = math.sqrt(1 - w * w)
Ek = E(math.rad(90), k)
lp = int(math.abs(p2 - p1) / 360) * 4 * Ek
if angle_eql(p1, p2) then lp = 4 * Ek end
while p1 < 0 do p1 = p1 + 360 end
while p1 >= 360 do p1 = p1 - 360 end
while p2 < 0 do p2 = p2 + 360 end
while p2 >= 360 do p2 = p2 - 360 end
if angle_eql(p1, p2) then return r * lp end
--if angle_eql(math.rad(360 - (p1 - p2) % 360), 0) then return r * lp end
n1 = int(p1 / 90) + 1
if n1 > 4 then n1 = 4 end
lp = lp + Ek * ( (n1 + 1) % 2) + E(math.rad(apa(n1, p1)), k) * (-1) ^ (n1 - 1)
n2 = int(p2 / 90) + 1
if n2 > 4 then n2 = 4 end
if n1 == n2 then n1 = n1 + 4 end
n3 = 2 * int( (n2 - 1) / 2) + 5
lp = lp + Ek * ( (n3 - n1) % 4) + E(math.rad(apa(n2, p2)), k) * (-1) ^ n2
if lp < 0 then lp = lp + 4 * Ek end
if lp > 4 * Ek then lp = lp - 4 * Ek end
return r * lp
end
function E(p, k)
local i, l, M
if k == 0 then
return p
end
if k == "" or k == nil then k = p; p = math.pi / 2 end
l = 0
if N > 1 then
for i = 1, int(N / 2) do l = l + __h__[i] * fx(__e__[i] * p, k) end
end
if N % 2 == 1 then
M = int(N / 2) + N % 2
l = l + __h__[M] * fx(__e__[M] * p, k) / 2
end -- 奇数個の場合
return l * p
end
function gear(bpa)
local ww
ww = bpa; if bpa > 1 then ww = 1 / bpa end
if bpa < 0 then
N = int(math.abs(bpa))
else
if ww == 0 or ww == "" then ww = 1 end
N = int(12 * (1.5 / ww))
if N > 300 then N = 300 end
end
eh(N)
return bpa
end
function eh(N) -- 積分点デ-タ
local I, J, E1, T, X0, PKM1, PK, T1, PKP1, PKM1
local DEN, D1, DPN, D2PN, D3PN, D4PN
local U, V, H, PP, DP, XI, FX, WI
local M = int(N / 2) + N % 2
__e__ = {}
__h__ = {}
E1 = N * (N + 1)
for I = 1, M do --DO 1
T = (4 * I - 1) * math.pi / (4 * N + 2)
X0 = (1. - (1. - 1. / N) / (8. * N * N)) * math.cos(T)
PKM1= 1.
PK = X0
for K = 2, N do --DO 3
T1 = X0 * PK
PKP1= T1 - PKM1 - (T1 - PKM1) / K + T1
PKM1= PK
PK = PKP1
end -- 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
end -- 1
end
function angle_eql(d1, d2, eps) --JW_CAD 線角コマンドに準ずる
local dd
if eps == "" or eps == nil then eps = 1e-15 end
dd = math.abs(d1 - d2)
while dd > math.pi - eps do dd = dd - math.pi end
return math.abs(dd) < eps and true or false
end
hs = {}; lg = ""
for line in io.lines("myfiles") do
F = {}
string.gsub(line, "%S+", function (x) table.insert(F, x) end)
if line:match("^hs") then
for i = 0, 15 do
hs[sprintf("%x", i)] = F[i+2]
end
end
if line:match("^lg[0-9a-f]") then
plg = line:sub(3); if lg == "" then lg = plg end
end
if line:match("^ci") then -- 指示円
r = F[4] * hs[lg]
p1 = F[5] and F[5] * 1 or 0
p2 = F[6] and F[6] * 1 or 360
w = F[7] and F[7] * 1 or 1
printf("h#円弧長 L = %.03f", arc_l(r, p1, p2, gear(w)))
end
end