jw_cad 外部変形 - (1287) luaで階段を割り付ける -

外部変形は データのやり取りをテキストファイルで行うので プログラム言語は 自由に選ぶことができます。図形は機能的かつシンプルなため、数多くのユーザーに受け入れられています。

 

luaで階段を割り付ける

:luaで階段を割り付ける
@echo off
set n=%1
if defined n (
  echo ^%1> %~dpn0.txt
) else (
  if exist %~dpn0.txt (
    for /f "tokens=*" %%a in (%~dpn0.txt) do set n=%%a
  )
)
if not defined n set n=12

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-%d 始点を指示してください
REM #2%d 終点を指示してください
REM #c 段数 = 
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 rot(x, d)
  if d == nil then return x end
  local x1, y1 = x[1], x[2]
  local co = math.cos(d)
  local si = math.sin(d)
  if type(x) == "table" then
    if type(x[1]) == "table" then
      local i
      for i = 1, #x do x[i] = rot(x[i], d) end
      return x
    end
  end
  return {x1 * co - y1 * si, x1 * si + y1 * co}
end

function ptspan(x, y, d, n)
  --d : 角度rad
  if d == nil then d = 0 end
  if n == nil then
    return lnspan({x[1], x[2], y[1], y[2]}, d)
  else
    w, h = unpack(lnspan({x[1], x[2], y[1], y[2]}, d))
    c = int( (n - int(n)) * 10)
    n = int(n)
    b = c ~= 0 and (n == 1 and w or w / (n - 1)) or w / n
    return {b, h / n}
  end
end

function lnspan(s, d) --線の dx, dy を返す
  --d : 角度rad
  if d == nil then d = 0 end
  local si = math.sin(d)
  local co = math.cos(d)
  local x1, y1, x2, y2 = s[1], s[2], s[3], s[4]
  local dx =   (x2 - x1) * co + (y2 - y1) * si
  local dy = - (x2 - x1) * si + (y2 - y1) * co
  return {dx, dy}
end

function int(a) return a < 0 and math.ceil(a) or math.floor(a) end

function step(p1, p2, n, d)
  w, h = unpack(ptspan(p1, p2, math.rad(d)))
  a = h / n
  b = n > 1 and w / (n - 1) or w
  p0 = rot({b, a}, math.rad(d))
  p2 = polarto(p1, a, math.rad(d + 90))
  for i = 1, n do
    echo(p1, p2); p1 = moveto(p1, p0)
    echo(p2, p1); p2 = moveto(p2, p0)
  end
end

n = os.getenv('n')*1
if n == 0 then n = 12 end
hp = {}
for line in io.lines("myfiles") do
  F = {}
  string.gsub(line, "%S+", function (x) table.insert(F, x) end)
  if line:match("^hk") then hk = F[2]*1 end
  if line:match("^hp([1-9])") then
    hp[line:match("^hp([1-9])")*1] = {F[2]*1, F[3]*1}
  end
end
step(hp[1], hp[2], n, hk)