Qwer1243 发表于 2024-9-24 09:19:15

分享一个可以画斜线15°外廓线的代码

本帖最后由 Qwer1243 于 2024-9-25 09:45 编辑

在放样水撑和柱撑详图的过程中可能会用到,有需要的可以看一下;有优化意见的欢迎分享

感谢黄明儒大师提供的界面函数和优化思路,下面代码已更新,增加了参数界面,水平线和竖直线也已适用(defun C:e7 (/ dialog getdata setdata do1 DCLID FN FNAME)
(defun dialog      ()
    (setq fname (vl-filename-mktemp nil nil ".dcl"))
    (setq fn (open fname "w"))
    (write-line      "HHbianban : dialog{label=\"连接板放样\";"
                fn
    )
    (write-line      " :edit_box{label=\"边距 (mm)\";key=\"key1\";value=\"20\";}"
                fn
    )
    (write-line      " :edit_box{label=\"角度(mm)\";key=\"key2\";value=\"15\";}"
                fn
    )
    (write-line      " :edit_box{label=\"距离端线长度\";key=\"key3\";value=\"100\";}"
                fn
    )
    (write-line " ok_cancel;" fn)
    (write-line "}" fn)
    (close fn)
)

(defun getdata (/ DCLDATA I KEY)
    (setq i 0)
    (repeat 3                                                    ;"key1"到"key5"
      (setq i (1+ i))
      (setq key (strcat "key" (itoa i)))
      (set (read key) (get_tile key))
      (setq DCLData (cons (cons key (eval (read key))) DCLData))
    )
    (Setenv "HHbianban" (VL-PRIN1-TO-STRING DCLData))
)

(defun setdata (/ DCLDATA X)
    (cond ((setq DCLData (getenv "HHbianban"))
         (setq DCLData (read DCLData))
         (mapcar '(lambda (x) (Set_tile (car x) (cdr x))) DCLData)
          )
    )
)

(defun do1 (/ ang c data line m m_perp numb1 numb2 numb3 pt pt1 pt2 pt3 pt4 x x1 x2 y_proj y1 y2)
    (setvar "cmdecho" 0)
    (while (setq line (entsel "\n选择直线: "))
      (setq pt (getpoint "\n请指定方向: "))
      (setq data (entget (car line)))
      (setq x1 (cadr (assoc 10 data)) x2 (cadr (assoc 11 data)) y1 (caddr (assoc 10 data)) y2 (caddr (assoc 11 data)))
      
      ;;读取面板数值
      (setq numb1 (atof key1) numb2 (atof key2) numb3 (atof key3))
      
      ;;选择直线为水平线
      (if (= y1 y2)
      (progn
          (princ "\n为水平线")
          (setq ang (/ pi 2))
          (if (< x1 x2)
            (progn
            (setq pt1 (cdr (assoc 10 data))) ; 获取直线的第一个点
            (setq pt2 (cdr (assoc 11 data))) ; 获取直线的第二个点)
            )
            (progn
            (setq pt2 (cdr (assoc 10 data))) ; 获取直线的第一个点
            (setq pt1 (cdr (assoc 11 data))) ; 获取直线的第二个点)
            )
          )
          (if (> (cadr pt) y1)
            (progn
            (princ "\n点在直线上方。")
            (setq pt1 (polar pt1 (* pi (/ 270 180.0)) numb3)) ;远离端线
            (setq pt2 (polar pt2 (* pi (/ 270 180.0)) numb3)) ;远离端线
            (setq pt1 (polar pt1 (* pi (/ 180 180.0)) numb1)) ;边距
            (setq pt2 (polar pt2 (* pi (/ 0 180.0)) numb1)) ;边距
            (setq pt3 (polar pt1 (+ ang (* pi (/ numb2 180.0))) 300)) ;numb2°斜线
            (setq pt4 (polar pt2 (- ang (* pi (/ numb2 180.0))) 300)) ;numb2°斜线
            )
            (progn
            (princ "\n点在直线下方。")
            (setq pt1 (polar pt1 (* pi (/ 90 180.0)) numb3)) ;远离端线
            (setq pt2 (polar pt2 (* pi (/ 90 180.0)) numb3)) ;远离端线
            (setq pt1 (polar pt1 (* pi (/ 180 180.0)) numb1)) ;边距
            (setq pt2 (polar pt2 (* pi (/ 0 180.0)) numb1)) ;边距
            (setq pt3 (polar pt1 (- ang (* pi (/ (+ 180 numb2) 180.0))) 300)) ;numb2°斜线
            (setq pt4 (polar pt2 (+ ang (* pi (/ (+ 180 numb2) 180.0))) 300)) ;numb2°斜线
            )
          )
      )
      )
      
      ;;选择直线为竖直线
      (if (= x1 x2)
      (progn
          (princ "\n为竖直线")
          (setq ang 0)
          (if (< y1 y2)
            (progn
            (setq pt1 (cdr (assoc 10 data))) ; 获取直线的第一个点
            (setq pt2 (cdr (assoc 11 data))) ; 获取直线的第二个点)
            )
            (progn
            (setq pt2 (cdr (assoc 10 data))) ; 获取直线的第一个点
            (setq pt1 (cdr (assoc 11 data))) ; 获取直线的第二个点)
            )
          )
          (if (> (car pt) x1)
            (progn
            (princ "\n点在直线右侧。")
            (setq pt1 (polar pt1 (* pi (/ 180 180.0)) numb3)) ;远离端线
            (setq pt2 (polar pt2 (* pi (/ 180 180.0)) numb3)) ;远离端线
            (setq pt1 (polar pt1 (* pi (/ 270 180.0)) numb1)) ;边距
            (setq pt2 (polar pt2 (* pi (/ 90 180.0)) numb1)) ;边距
            (setq pt3 (polar pt1 (- ang (* pi (/ numb2 180.0))) 300)) ;numb2°斜线
            (setq pt4 (polar pt2 (+ ang (* pi (/ numb2 180.0))) 300)) ;numb2°斜线
            )
            (progn
            (princ "\n点在直线左侧。")
            (setq pt1 (polar pt1 (* pi (/ 0 180.0)) numb3)) ;远离端线
            (setq pt2 (polar pt2 (* pi (/ 0 180.0)) numb3)) ;远离端线
            (setq pt1 (polar pt1 (* pi (/ 270 180.0)) numb1)) ;边距
            (setq pt2 (polar pt2 (* pi (/ 90 180.0)) numb1)) ;边距
            (setq pt3 (polar pt1 (+ ang (* pi (/ (+ 180 numb2) 180.0))) 300)) ;numb2°斜线
            (setq pt4 (polar pt2 (- ang (* pi (/ (+ 180 numb2) 180.0))) 300)) ;numb2°斜线
            )
          )
      )
      )
      
      ;;选择直线为斜线
      (if (and (/= x1 x2) (/= y1 y2))
      (progn
          (princ "\n为斜线")
          (if (< y1 y2)
            (progn
            (setq pt1 (cdr (assoc 10 data))) ; 获取直线的第一个点
            (setq pt2 (cdr (assoc 11 data))) ; 获取直线的第二个点)
            )
            (progn
            (setq pt2 (cdr (assoc 10 data))) ; 获取直线的第一个点
            (setq pt1 (cdr (assoc 11 data))) ; 获取直线的第二个点)
            )
          )
         
          ; 计算斜率 m 和截距 c
          (setq m (/ (- (cadr pt2) (cadr pt1)) (- (car pt2) (car pt1))))
          (setq c (- (cadr pt1) (* m (car pt1))))
         
          ; 计算垂直线的斜率
          (setq m_perp (- (/ 1 m)))
         
          ; 计算角度
          (setq ang (atan m_perp))
         
          ;计算点 P 到直线的垂直投影点的 y 坐标
          (setq x (car pt))
          (setq y_proj (+ (* m x) c))
         
          ;判断点的位置
          (if (> ang 0)
            (if (> (cadr pt) y_proj)
            (progn
                (princ "\n点在直线上方。")
                (setq pt1 (polar pt1 (+ ang (* pi (/ 180 180.0))) numb3)) ;远离端线
                (setq pt2 (polar pt2 (+ ang (* pi (/ 180 180.0))) numb3)) ;远离端线
                (setq pt1 (polar pt1 (- ang (* pi (/ 90 180.0))) numb1)) ;边距
                (setq pt2 (polar pt2 (+ ang (* pi (/ 90 180.0))) numb1)) ;边距
                (setq pt3 (polar pt1 (- ang (* pi (/ numb2 180.0))) 300)) ;numb2°斜线
                (setq pt4 (polar pt2 (+ ang (* pi (/ numb2 180.0))) 300)) ;numb2°斜线
            )
            (progn
                (princ "\n点在直线下方。")
                (setq pt1 (polar pt1 ang numb3)) ;远离端线
                (setq pt2 (polar pt2 ang numb3)) ;远离端线
                (setq pt1 (polar pt1 (- ang (* pi (/ 90 180.0))) numb1)) ;边距
                (setq pt2 (polar pt2 (+ ang (* pi (/ 90 180.0))) numb1)) ;边距
                (setq pt3 (polar pt1 (+ ang (* pi (/ (+ 180 numb2) 180.0))) 300)) ;numb2°斜线
                (setq pt4 (polar pt2 (- ang (* pi (/ (+ 180 numb2) 180.0))) 300)) ;numb2°斜线
            )
            )
            (if (> (cadr pt) y_proj)
            (progn
                (princ "\n点在直线上方。")
                (setq pt1 (polar pt1 ang numb3)) ;远离端线
                (setq pt2 (polar pt2 ang numb3)) ;远离端线
                (setq pt1 (polar pt1 (- ang (* pi (/ 90 180.0))) numb1)) ;边距
                (setq pt2 (polar pt2 (+ ang (* pi (/ 90 180.0))) numb1)) ;边距
                (setq pt3 (polar pt1 (+ ang (* pi (/ (+ 180 numb2) 180.0))) 300)) ;numb2°斜线
                (setq pt4 (polar pt2 (- ang (* pi (/ (+ 180 numb2) 180.0))) 300)) ;numb2°斜线
            )
            (progn
                (princ "\n点在直线下方。")
                (setq pt1 (polar pt1 (+ ang (* pi (/ 180 180.0))) numb3)) ;远离端线
                (setq pt2 (polar pt2 (+ ang (* pi (/ 180 180.0))) numb3)) ;远离端线
                (setq pt1 (polar pt1 (- ang (* pi (/ 90 180.0))) numb1)) ;边距
                (setq pt2 (polar pt2 (+ ang (* pi (/ 90 180.0))) numb1)) ;边距
                (setq pt3 (polar pt1 (- ang (* pi (/ numb2 180.0))) 300)) ;numb2°斜线
                (setq pt4 (polar pt2 (+ ang (* pi (/ numb2 180.0))) 300)) ;numb2°斜线
            )
            )
          )
      )
      )
      
      (entmakeX (list '(0 . "LINE") (cons 10 pt1) (cons 11 pt2)))
      (entmakeX (list '(0 . "LINE") (cons 10 pt1) (cons 11 pt3)))
      (entmakeX (list '(0 . "LINE") (cons 10 pt2) (cons 11 pt4)))
      (princ "\n~~~~~~~~~~~分割线~~~~~~~~~~~")
    )
    (princ return#)
)

(dialog)
(setq dclid (load_dialog fname))
(new_dialog "HHbianban" dclid)
(setdata)
(action_tile "accept" "(getdata)(done_dialog 1)")
(action_tile "cancel" "(getdata)(done_dialog 0)")
(setq return# (start_dialog))
(unload_dialog dclid)
(vl-file-delete fname)
(cond ((equal return# 1) (do1)))
)

自贡黄明儒 发表于 2024-9-24 11:54:12

本帖最后由 自贡黄明儒 于 2024-9-29 11:57 编辑

Qwer1243 发表于 2024-9-24 11:45
我不会做面板,你要是方便的话可以帮忙更新一下面板,我刚才重新上传了代码,水平和竖直线不会报错了
(defun C:Ban (/ dialog getdata setdata do1 DCLID FN FNAME)
(defun dialog      ()
    (setq fname (vl-filename-mktemp nil nil ".dcl"))
    (setq fn (open fname "w"))
    (write-line      "HHbianban : dialog{label=\"画边板 黄明儒\";"
                fn
    )
    (write-line      " :edit_box{label=\"边距 (mm)\";key=\"key1\";value=\"20\";}"
                fn
    )
    (write-line      " :edit_box{label=\"角度(mm)\";key=\"key2\";value=\"15\";}"
                fn
    )
    (write-line      " :edit_box{label=\"离端部 倍数\";key=\"key3\";value=\"1.5\";}"
                fn
    )
    (write-line " ok_cancel;" fn)
    (write-line "}" fn)
    (close fn)
)

(defun getdata (/ DCLDATA I KEY)
    (setq i 0)
    (repeat 3                                                    ;"key1"到"key5"
      (setq i (1+ i))
      (setq key (strcat "key" (itoa i)))
      (set (read key) (get_tile key))
      (setq DCLData (cons (cons key (eval (read key))) DCLData))
    )
    (Setenv "HHbianban" (VL-PRIN1-TO-STRING DCLData))
)

(defun setdata (/ DCLDATA X)
    (cond ((setq DCLData (getenv "HHbianban"))
         (setq DCLData (read DCLData))
         (mapcar '(lambda (x) (Set_tile (car x) (cdr x))) DCLData)
          )
    )
)

   (defun do1 ()
    (ACET-UNDO-BEGIN)                                          ;编组
    (setq e0 (entlast))
    (if      (setq e (entsel "\n 型钢端线:"))
      (progn
      (setq p0 (cadr e))
      (setq obj (vlax-ename->vla-object (car e)))
      (setq key3 (* (distof key3) (vlax-get obj 'length)))
      (setq key3 (VL-PRINC-TO-STRING key3))
      (vl-cmdf "_offset" key3 e pause "")
      )
    )
    ;;如果偏移成功
    (setq e (entlast))
    (if      (not (equal e e0))
      (do2 e)
    )
    (ACET-UNDO-END)
)


;;与PPCAD保持一致
(if (not (tblsearch "layer" "4虚线层"))
    (vl-cmdf "_layer" "_M" "4虚线层" "_C" 6 "" "L" "DASHED" "" "")
)

(dialog)
(setq dclid (load_dialog fname))
(new_dialog "HHbianban" dclid)
(setdata)
(action_tile "accept" "(getdata)(done_dialog 1)")
(action_tile "cancel" "(getdata)(done_dialog 0)")
(setq return# (start_dialog))
(unload_dialog dclid)
(vl-file-delete fname)
(cond ((equal return# 1) (do1)))
)

do2就交给你了

lzspain 发表于 2024-9-25 08:57:30

运行时报错
当前图层:0
输入选项 [?/生成(M)/设置(S)/新建(N)/重命名(R)/开(ON)/关(OFF)/颜色(C)/线型(L)/线宽(LW)/透明度(TR)/材质(MAT)/打印(P)/冻结(F)/解冻(T)/锁定(LO)/解锁(U)/状态(A)/说明(D)/协调(E)/外部参照(X)]: _M
输入新图层的名称 (成为当前图层) <0>: 4虚线层 输入选项 [?/生成(M)/设置(S)/新建(N)/重命名(R)/开(ON)/关(OFF)/颜色(C)/线型(L)/线宽(LW)/透明度(TR)/材质(MAT)/打印(P)/冻结(F)/解冻(T)/锁定(LO)/解锁(U)/状态(A)/说明(D)/协调(E)/外部参照(X)]: _C
新颜色 [真彩色(T)/配色系统(CO)] : 6
输入图层名列表,这些图层使用颜色 6 (洋红) <4虚线层>: 输入选项 [?/生成(M)/设置(S)/新建(N)/重命名(R)/开(ON)/关(OFF)/颜色(C)/线型(L)/线宽(LW)/透明度(TR)/材质(MAT)/打印(P)/冻结(F)/解冻(T)/锁定(LO)/解锁(U)/状态(A)/说明(D)/协调(E)/外部参照(X)]: L
输入已加载的线型名或 [?] <Continuous>: DASHED
输入使用线型“DASHED”的图层名列表 <4虚线层>: 输入选项 [?/生成(M)/设置(S)/新建(N)/重命名(R)/开(ON)/关(OFF)/颜色(C)/线型(L)/线宽(LW)/透明度(TR)/材质(MAT)/打印(P)/冻结(F)/解冻(T)/锁定(LO)/解锁(U)/状态(A)/说明(D)/协调(E)/外部参照(X)]:
命令: ; 错误: 参数太多

Qwer1243 发表于 2024-9-24 10:27:15

自贡黄明儒 发表于 2024-9-24 10:14
机械行业同行呀,这个不错。以往我都是手画的。
选择角钢端部那条线,每边留20mm,以便于焊接,再沿角钢另 ...

我是钢结构深化的,经常会用到,两边的却是经常预留20mm,是不是规范我也不清楚

自贡黄明儒 发表于 2024-9-24 10:14:19

机械行业同行呀,这个不错。以往我都是手画的。
选择角钢端部那条线,每边留20mm,以便于焊接,再沿角钢另一边移动一个距离(不知道这个距离有没有规范要求),这样更智能。

tiancao100 发表于 2024-9-24 10:19:26

这不钢结构嘛, 必须15度吗? 不能自动剪裁

自贡黄明儒 发表于 2024-9-24 10:25:21

tiancao100 发表于 2024-9-24 10:19
这不钢结构嘛, 必须15度吗? 不能自动剪裁

这个角度应该是个变值,可以取0度。关键楼主点取那条线,到角钢端部,有没有规范要求。

Qwer1243 发表于 2024-9-24 10:28:33

tiancao100 发表于 2024-9-24 10:19
这不钢结构嘛, 必须15度吗? 不能自动剪裁

15度,可以在代码里面调整,一般都是15度,我就没添加调整参数

自贡黄明儒 发表于 2024-9-24 11:23:02

本帖最后由 自贡黄明儒 于 2024-9-24 14:54 编辑



Qwer1243 发表于 2024-9-24 10:28
15度,可以在代码里面调整,一般都是15度,我就没添加调整参数
弄个界面,适应各种情况

Qwer1243 发表于 2024-9-24 11:42:50

我更新了一下代码,可以使用与水平和竖直线了@xyp1964

Qwer1243 发表于 2024-9-24 11:45:05

自贡黄明儒 发表于 2024-9-24 11:23
弄个界面,适应各种情况

我不会做面板,你要是方便的话可以帮忙更新一下面板,我刚才重新上传了代码,水平和竖直线不会报错了
页: [1] 2 3 4
查看完整版本: 分享一个可以画斜线15°外廓线的代码