jw_cad 外部変形 - (1280) luaで2線の交角を計算する -

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

 

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))