外部変形は データのやり取りをテキストファイルで行うので プログラム言語は 自由に選ぶことができます。図形は機能的かつシンプルなため、数多くのユーザーに受け入れられています。
luaで2線の交角を計算する
:luaで2線の交角を計算する
@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 #1%dln 線を指示してください
REM #2%dln 線を指示してください
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 join(a, FS)
if type(a) ~= "table" then return a end
if FS == nil then FS = " " end
return table.concat(flatten(a), FS)
end
function flatten(a)
local i, j, k
local c = {}
for i in pairs(a) do
if type(a[i]) == "table" then
--while #a[i] == 1 do a[i] = a[i][1] end
for j in pairs(a[i]) do
if type(a[i][j]) == "table" then
--while #a[i][j] == 1 do a[i][j] = a[i][j][1] end
for k in pairs(a[i][j]) do
table.insert(c, a[i][j][k])
end
else
table.insert(c, a[i][j])
end
end
else
table.insert(c, a[i])
end
end
return c
end
function echo(...)
if #{...} == 0 then return end
return print(join({select(1, ...)}))
end
function lnlength(s) --線長を返す
local x1, y1, x2, y2 = s[1], s[2], s[3], s[4]
return math.sqrt( (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))
end
function lnslope(s) --線の角度を返す
local x1, y1, x2, y2 = s[1], s[2], s[3], s[4]
return math.atan2(y2 - y1, x2 - x1)
end
function lnpoint(s, pm) --始点 pm=-1, 終点 pm=1 の座標を返す
local x1, y1, x2, y2 = s[1], s[2], s[3], s[4]
if pm == nil then pm = 0 end
return pm == 0 and {(x1 + x2) / 2, (y1 + y2) / 2} or (pm < 0 and {x1, y1} or {x2, y2})
end
function ln_hpsnap(s, p) --線の吸着点を返す
local t, d
t = ln_hpdist(s, p)
d = lnslope(s)
return {p[1] + t * math.sin(d), p[2] - t * math.cos(d)}
end
function ln_hpdist(s, p) --線と点の最短距離を返す
local x = {p[1], p[2], s[1], s[2]}
return lnlength(x) * math.sin(lnslope(s) - lnslope(x))
end
function line_x_poi(ln1, ln2) -- 線と線の交点
if type(ln1) == "number" then ln1 = ln(ln1) end
if #ln1 < 4 then ln1 = flatten(ln1) end
local x1, y1, x2, y2 = ln1[1], ln1[2], ln1[3], ln1[4]
local dx1 = x2 - x1
local dy1 = y2 - y1
local m1 = dx1 == 0 and 1e20 or dy1 / dx1
if type(ln2) == "number" then ln2 = ln(ln2) end
if #ln2 < 4 then ln2 = flatten(ln2) end
local x3, y3, x4, y4 = ln2[1], ln2[2], ln2[3], ln2[4]
local dx2 = x4 - x3
local dy2 = y4 - y3
local m2 = dx2 == 0 and 1e20 or dy2 / dx2
local aa = m1 - m2
if math.abs(aa) < 1e-10 then aa = 0 end
if aa ~= 0 then
local b1 = y1 - m1 * x1
local b2 = y3 - m2 * x3
return {(b2 - b1) / aa, (m1 * b2 - m2 * b1) / aa}, aa
else
local p1, p2 = lnpoint(ln1, -1), lnpoint(ln1, 1)
local p3, p4 = lnpoint(ln2, -1), lnpoint(ln2, 1)
if ptdist(p2, p3) < 1e-12 then return p2, aa end
if ptdist(p1, p4) < 1e-12 then return p1, aa end
if ptdist(p2, p4) < 1e-12 then return p2, aa end
if ptdist(p1, p3) < 1e-12 then return p1, aa end
print("heline_x_poi:処理できません"); os.exit()
end
end
function sgn(x) return x == 0 and 0 or ( x > 0 and 1 or -1 ) end
function ptslope(x, y)
local x1, y1 = x[1], x[2]
local x2, y2 = y[1], y[2]
return math.atan2(y2 - y1, x2 - x1)
end
hp = {}; ln = {}
for line in io.lines("myfiles") do
F = {}
string.gsub(line, "%S+", function (x) table.insert(F, x) end)
if line:match("^hp[1-9]") then
hp[F[1]:gsub("hp", ""):gsub("ln", ""):gsub("-", "")*1] = {F[2], F[3]}
end
if line:match("^hhp[1-9]ln") then
lnn = line:gsub("hhp", ""):gsub("ln", "")*1
end
if line:match("^ ") and #F == 4 then ln[lnn] = F end
end
pc, aa = line_x_poi(ln[1], ln[2])
if aa ~= 0 then
p1 = ln_hpsnap(ln[1], hp[1])
p2 = ln_hpsnap(ln[2], hp[2])
d2 = ptslope(pc, p2)
d1 = ptslope(pc, p1)
xang = math.deg(d2 - d1)
else
xang = 0
end
if sgn(xang - 180) == 1 then xang = xang - 360 end
if sgn(xang + 180) ==-1 then xang = xang + 360 end
printf("h#2線の交角 = ∠%.6f゚ : d1=%.6f゚ : d2=%.6f゚", xang, math.deg(d1), math.deg(d2))