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

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

 

clispで階段を割り付ける

:clispで階段を割り付ける
@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 (
  more +%%n %0 | clisp -q > nul
)
goto:eof

REM #jww
REM #1-%d 始点を指示してください
REM #2%d 終点を指示してください
REM #c 段数 = 
REM #e

#!この次の行からプログラムを書いてください
;ユーザ定義関数
( ;文字列 "x" を 数値 xd0 (倍精度 double-float) に変換
  defun to_f (x)
    (if (equal x nil) (setq x "0"))
    (if (listp x)
        (mapcar #'to_f x)
        (progn
          (if (typep x 'double-float)
              x
              (progn
                (if (stringp x) nil (setq x (write-to-string x)))
                (if (search "e" x)
                    (progn
                      (setq s (search "e" x))
                      (read-from-string
                        (concatenate 'string (subseq x 0 s) "d" (subseq x (+ 1 s) (length x)))
                      )
                    ) ;progn (search "e" x)
                    (if (search "d" x)
                        x
                        (read-from-string
                          (concatenate 'string x "d0")
                        )
                    )
                )
              ) ;progn (typep x 'double-float)
          )
        ) ;progn (listp x)
    )
)
(defun to_s (x) ;数値 xd0 (倍精度 double-float) を 文字列 "x" に変換
(let (s)
  (if (equal x nil) (setq x 0))
  (if (listp x)
      (mapcar #'to_s x)
      (progn
        (if (stringp x) nil (setq x (write-to-string x)))
        (if (search "d0" x)
            (subseq x 0 (search "d" x))
            (if (search "d" x)
                (progn
                  (setq s (search "d" x))
                  (concatenate 'string
                    (subseq x 0 s) "e" (subseq x (+ 1 s) (length x)))
                )
                x
            )
        )
      ) ;progn (listp x)
  )
))
( ;文字列 "x" を 整数に変換
  defun to_i (x)
    (if (numberp x)
        (* (signum x) (floor (abs x)))
        (progn
          (if (equal x nil) (setq x "0"))
          (if (listp x)
              (mapcar #'to_i x)
              (progn
                (if (stringp x) nil (setq x (write-to-string x)))
                (parse-integer x)
              )
          )
        )
    )
)
;角度を deg から rad に変換する
(defun rad (x) (setq x (* x (/ pi 180))))
;点 x を 相対距離 y 移動する
(defun moveto (x y)
  (if y
    (loop for i in x
          for j in y
            collect (+ i j)
    )
      x
  )
)
;線の dx, dy を返す
;dx pm=-1,  dy pm=1 を返す
(defun lnspan (ln &optional (pm 0))
  (setq x1 (to_f (nth 0 ln)))
  (setq y1 (to_f (nth 1 ln)))
  (setq x2 (to_f (nth 2 ln)))
  (setq y2 (to_f (nth 3 ln)))
  (setq dx (- x2 x1))
  (setq dy (- y2 y1))
  (case pm
    ( (0) (list dx dy))
    ( (-1) dx)
    ( (1) dy)
  )
)
(defun ptspan (x y &optional (pm 0))
  (lnspan (append x y) pm)
)
(defun rot (x &optional (d 0))
;回転による点の座標変換(部材系→全体系)
  (setq si (sin d))
  (setq co (cos d))
  (setq n (length x))
  (case n
    ( (2)(progn
        (multiple-value-setq (x1 y1) (values-list (to_f x)))
        (list (- (* x1 co) (* y1 si))
              (+ (* x1 si) (* y1 co)))
    ))
    ( (3)(progn
        (multiple-value-setq (x1 y1 r) (values-list (to_f x)))
        (list (- (* x1 co) (* y1 si))
              (+ (* x1 si) (* y1 co)) r)
    ))
    ( (4)(progn
        (multiple-value-setq (x1 y1 x2 y2) (values-list (to_f x)))
        (list (- (* x1 co) (* y1 si))
              (+ (* x1 si) (* y1 co))
              (- (* x2 co) (* y2 si))
              (+ (* x2 si) (* y2 co)))
    ))
    ( (5)(progn
        (multiple-value-setq (x1 y1 u v w) (values-list (to_f x)))
        (list (- (* x1 co) (* y1 si))
              (+ (* x1 si) (* y1 co)) u (+ v (* d (/ 180 pi))) w)
    ))
    ( (6)(progn
        (multiple-value-setq (s x1 y1 lx ly str) (values-list (to_f x)))
        (list s
              (- (* x1 co) (* y1 si))
              (+ (* x1 si) (* y1 co))
              (- (* lx co) (* ly si))
              (+ (* lx si) (* ly co)) str)
    ))
    ( (7)(progn
        (multiple-value-setq (x1 y1 r p1 p2 w d2) (values-list (to_f x)))
        (list (- (* x1 co) (* y1 si))
              (+ (* x1 si) (* y1 co)) r p1 p2 w (+ d2 (* d (/ 180 pi))))
    ))
  )
)
(defun rot2 (x &optional (d 0))
;回転による点の座標変換(全体系→部材系)
  (setq si (sin d))
  (setq co (cos d))
  (setq n (length x))
  (case n
    ( (2)(progn
        (multiple-value-setq (x1 y1) (values-list (to_f x)))
        (list (+ (* x1 co) (* y1 si))
              (- (* y1 co) (* x1 si)))
    ))
    ( (3)(progn
        (multiple-value-setq (x1 y1 r) (values-list (to_f x)))
        (list (+ (* x1 co) (* y1 si))
              (- (* y1 co) (* x1 si)) r)
    ))
    ( (4)(progn
        (multiple-value-setq (x1 y1 x2 y2) (values-list (to_f x)))
        (list (+ (* x1 co) (* y1 si))
              (- (* y1 co) (* x1 si))
              (+ (* x2 co) (* y2 si))
              (- (* y2 co) (* x2 si)))
    ))
    ( (5)(progn
        (multiple-value-setq (x1 y1 u v w) (values-list (to_f x)))
        (list (+ (* x1 co) (* y1 si))
              (- (* y1 co) (* x1 si)) u (+ v (* d (/ 180 pi))) w)
    ))
    ( (6)(progn
        (multiple-value-setq (s x1 y1 lx ly str) (values-list (to_f x)))
        (list s
              (+ (* x1 co) (* y1 si))
              (- (* y1 co) (* x1 si))
              (+ (* lx co) (* ly si))
              (- (* ly co) (* lx si)) str)
    ))
    ( (7)(progn
        (multiple-value-setq (x1 y1 r p1 p2 w d2) (values-list (to_f x)))
        (list (+ (* x1 co) (* y1 si))
              (- (* y1 co) (* x1 si)) r p1 p2 w (+ d2 (* d (/ 180 pi))))
    ))
  )
)
( ;階段を割り付ける
  defun steps (g p1 p2 n hk &optional (c 1))
  (setq d (rad hk))
  (multiple-value-setq (ww hh) (values-list (rot2 (ptspan p1 p2) d)))
    (setq aa (/ hh n))
    (if (> n 1) (setq bb (/ ww (- n c))) (setq bb ww))
    (setq p0 (rot (list bb aa) d))
    (setq p2 (moveto p1 (rot (list 0 aa) d)))
    (setq p3 (moveto p1 p0))
    (loop for i from 1 to n
     do
      (format g "~{ ~a~}~{ ~a~}~%" (to_s p1) (to_s p2))
      (format g "~{ ~a~}~{ ~a~}~%" (to_s p2) (to_s p3))
      (multiple-value-setq (p1 p2 p3) (values-list (list p3 (moveto p2 p0) (moveto p3 p0))))
    )
)

;本文
( ;jwc_temp.txt から 入力
  with-open-file (f "jwc_temp.txt" :direction :input)
  (loop for line = (read-line f nil) while line do
    (setq a (regexp:regexp-split "\\s\\+" line))
    (if (regexp:match "^hk" line) (setq hk (cadr a)))
    (if (regexp:match "^hp1" line) (setq hp1 (cdr a)))
    (if (regexp:match "^hp2" line) (setq hp2 (cdr a)))
  )
)
( ;準備計算
  progn
  (setq n (to_i (ext:getenv "n")))
  (if (= n 0) (setq n 12))
  (setq hk (to_f hk))
  (setq hp1 (to_f hp1))
  (setq hp2 (to_f hp2))
)
( ;jwc_temp.txt へ 出力
  with-open-file (g "jwc_temp.txt" :direction :output)
    (steps g hp1 hp2 n hk)
)