外部変形は データのやり取りをテキストファイルで行うので プログラム言語は 自由に選ぶことができます。図形は機能的かつシンプルなため、数多くのユーザーに受け入れられています。
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 #1ln 線を指示してください
REM #bz
REM #e
#!この次の行からプログラムを書いてください
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 polar(r, d, w) --方向余弦のセット
if r == "" or r == nil then r = 1 end
if d == "" or d == nil then d = 0 end
if w == "" or w == nil then w = 1 end
return {r * math.cos(d), r * math.sin(d) * w}
end
function moveto(x, y) --点x を 相対距離 y [ a, b ] へ移動
return y and ptcalc("+", x, y) or x
end
function polarto(x, r, d, w) --点x を 極座標 [ r, d ] で相対的に移動する
return moveto(x, polar(r, d, w))
end
function ptcalc(p, x, y) --点データの数値演算(加減乗除)
local zz
zz = {x[1], x[2], y[1], y[2]}
if p == "+" then
return zz and {zz[1] + zz[3], zz[2] + zz[4]} or {0, 0}
elseif p == "-" then
return zz and {zz[1] - zz[3], zz[2] - zz[4]} or {0, 0}
elseif p == "*" then
return zz and {zz[1] * zz[3], zz[2] * zz[4]} or {0, 0}
elseif p == "/" then
return zz and {zz[1] / zz[3], zz[2] / zz[4]} or {0, 0}
elseif p == "ave" then
return zz and {(zz[1] + zz[3]) / 2, (zz[2] + zz[4]) / 2} or {0, 0}
else
return {0, 0}
end
end
function ptdist(x, y)
local x1, y1 = x[1], x[2]
local x2, y2 = y[1], y[2]
return math.sqrt( (x2 - x1) ^ 2 + (y2 - y1) ^ 2)
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 arrow(pt1, d, size, xang, xan2)
if d == nil then d = 0 end
if size == nil then size = 3 end
if xang == nil then xang = 45 end
if xan2 == nil then xan2 = 120 end
local l, a, pt2, pt3, pt4, c
l = size
a = math.rad(xang) / 2
pt2 = polarto(pt1, l, d - a)
pt4 = polarto(pt1, l, d + a)
if xan2 == 180 then
echo("sl", pt1, pt2, pt4)
else
c = math.cos(a) - math.sin(a) * math.tan(math.rad(90 - xan2 / 2))
pt3 = polarto(pt1, l * c, d)
echo("sl", pt1, pt2, pt3, pt4)
end
end
function ln_hpends(s, p)
local l1, l2
l1 = ptdist(p, lnpoint(s,-1))
l2 = ptdist(p, lnpoint(s, 1))
return l1 < l2 and -1 or 1
end
for line in io.lines("myfiles") do
F = {}
string.gsub(line, "%S+", function (x) table.insert(F, x) end)
if line:match("^hp1ln") then
p1 = {F[2], F[3]}
end
if line:match("^ ") then
if #F == 4 then
size = 5 --矢印の長さ( 図寸 )
xang = 45 --矢印の交角( ゚ )
xan2 = 120 --矢尻の交角( ゚ )
d = lnslope(F)
pm = ln_hpends(F, p1)
print("bz")
arrow(lnpoint(F, pm), d, -pm*size, xang, xan2)
end
end
end