この掲示板は AutoCADマクロ屋本舗 の掲示板です。

【 注意 】最初に必ず ↓↓ 下記内容 ↓↓ を参照ください。
① マクロが分からない方は、まず 【 マクロ講座 】 を参照ください。
② 質問の前に 【 マクロ使用前の注意事項 】 をお読みください。
③ 質問する時は、新規投稿フォーム下の【 新規投稿時のお願い 】を必ずお読みください。

円弧法面のLISP
添付図の様に、既存の青い円弧に対して、
新たに、赤い長短の線を描画するLISPにしたい。
作成は可能でしょうか?
よろしくお願いします。
  • KAZ
  • MAIL
  • 2025/07/09 (Wed) 14:03:52
Re: 円弧法面のLISP
二つの円弧は同心円で、始点-中心-終点の角度が同じ。
分割数を指定して赤線を作図

という条件なら可能です。

赤線のそれぞれの座標を計算で出しても良いし。
DIVIDEコマンドを使った後に分割点座標を取得しても良いし。
LISPの練習をするには丁度良いかもしれません。(難易度低め)
  • Hamu
  • 2025/07/09 (Wed) 17:30:24
Re: 円弧法面のLISP
>二つの円弧は同心円で、始点-中心-終点の角度が同じ。

じゃなくても、等分割した点同士を赤線で繋ぐだけなら、難しくはないですね。
  • Hamu
  • 2025/07/09 (Wed) 17:33:40
Re: 円弧法面のLISP
分割数を入力して、外側の円弧をクリック、内側の円弧をクリック

(defun c:test ( / i j divpoint ent ss div edata center radius start_angle end_angle inc_angle current_angle pt_list pt_list1 pt_list2 p_start p_end wcs_pt ucs_pt)

(defun divpoint () ; 分割点の座標を取得するルーチン
(setq ent (ssname ss 0)) ; 選択された円弧のエンティティ名を取得
(setq edata (entget ent)) ; エンティティのデータリストを取得

(if (and div (>= div 2))
(progn ; 円弧の情報をWCSで取得
; DXFデータから取得される座標や角度は、常にWCSの基準です。
(setq center (cdr (assoc 10 edata))) ; 中心点
(setq radius (cdr (assoc 40 edata))) ; 半径
(setq start_angle (cdr (assoc 50 edata))) ; 開始角度 (ラジアン)
(setq end_angle (cdr (assoc 51 edata))) ; 終了角度 (ラジアン)
; 始点と終点の座標をWCSで計算
(setq p_start (list (+ (car center) (* radius (cos start_angle))) (+ (cadr center) (* radius (sin start_angle))) (caddr center)))
(setq p_end (list (+ (car center) (* radius (cos end_angle))) (+ (cadr center) (* radius (sin end_angle))) (caddr center)))

; 角度の正規化 (0から2πの範囲に調整)
(if (< end_angle start_angle)
(setq end_angle (+ end_angle (* 2 pi)))
)
; 円弧が360度の場合の調整
(if (equal (abs (- end_angle start_angle)) (* 2 pi) 1e-8)
(setq end_angle (+ start_angle (* 2 pi)))
)

; 始点座標をリストに追加 (WCS -> UCS 変換)
(setq wcs_pt p_start)
(setq ucs_pt (trans wcs_pt 0 1)) ; WCS (0) から現在のUCS (1) へ点を変換
(setq pt_list (cons ucs_pt pt_list))

; 等分割された点の計算 (WCSで計算後、UCSに変換)
(setq inc_angle (/ (- end_angle start_angle) div)) ; 分割ごとの角度増分

(setq i 1)
(while (< i div) ; 最後の点(終点)は別途追加するため、div-1回ループ
(setq current_angle (+ start_angle (* i inc_angle)))
(setq x (+ (car center) (* radius (cos current_angle))))
(setq y (+ (cadr center) (* radius (sin current_angle))))
(setq z (caddr center)) ; Z座標は中心のZ座標を使用
(setq wcs_pt (list x y z))
(setq ucs_pt (trans wcs_pt 0 1)) ; WCS (0) から現在のUCS (1) へ点を変換
(setq pt_list (cons ucs_pt pt_list))
(setq i (1+ i))
)

; 終点座標をリストに追加 (WCS -> UCS 変換)
(setq wcs_pt p_end)
(setq ucs_pt (trans wcs_pt 0 1)) ; WCS (0) から現在のUCS (1) へ点を変換
(setq pt_list (cons ucs_pt pt_list))

; リストを逆順にして、始点から終点への順にする(しなくても良いのだけれど、なんとなく)
(setq pt_list (reverse pt_list))

pt_list ; 取得したUCS座標リストを返す
)
nil
)
)

(setq pt_list '() pt_list1 nil pt_list2 nil) ; 座標リストを初期化

(if (setq div (getint "\n分割数を入力してください (1以上の整数): ")) (setq div (* 2 div)))
(princ "\n外側の円弧を選択してください: ")
(if div (setq ss (ssget ":s:e" '((0 . "ARC"))))) ; 円弧のみを選択

(if ss (setq pt_list1 (divpoint)))

(princ "\n内側の円弧を選択してください: ")
(if pt_list1 (setq ss (ssget ":s:e" '((0 . "ARC"))))) ; 円弧のみを選択
(setq pt_list '())
(if ss (setq pt_list2 (divpoint)))

(if pt_list2
(progn
(setq j 0)
(repeat (length pt_list1)
(if (eq 0 j) ; 偶数番目は半分の長さ
(command "line" "non" (car pt_list1) "non" (car pt_list2) "")
(command "line" "non" (car pt_list1) "non" (list (/ (+ (car (car pt_list1)) (car (car pt_list2))) 2.0) (/ (+ (cadr (car pt_list1)) (cadr (car pt_list2))) 2.0) (/ (+ (caddr (car pt_list1)) (caddr (car pt_list2))) 2.0)) "")
)
(setq pt_list1 (cdr pt_list1) pt_list2 (cdr pt_list2))
(setq j (nth j '(1 0)))
)
)
)
(princ)
)
  • Hamu
  • 2025/07/11 (Fri) 14:32:09
Re: 円弧法面のLISP
Hamu様へ

希望のLISP作成ありがとうございました。
完璧に作動しました。
大変助かりました。ありがとうございました。
  • KAZ
  • MAIL
  • 2025/07/12 (Sat) 07:40:24 New

返信フォーム






プレビュー (投稿前に内容を確認)