明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2216|回复: 32

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

[复制链接]
发表于 2024-9-24 09:19:15 | 显示全部楼层 |阅读模式
本帖最后由 Qwer1243 于 2024-9-25 09:45 编辑

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

感谢黄明儒大师提供的界面函数和优化思路,下面代码已更新,增加了参数界面,水平线和竖直线也已适用
  1. (defun C:e7 (/ dialog getdata setdata do1 DCLID FN FNAME)
  2.   (defun dialog        ()
  3.     (setq fname (vl-filename-mktemp nil nil ".dcl"))
  4.     (setq fn (open fname "w"))
  5.     (write-line        "HHbianban : dialog{label="连接板放样";"
  6.                 fn
  7.     )
  8.     (write-line        " :edit_box{label="边距 (mm)";key="key1";value="20";}"
  9.                 fn
  10.     )
  11.     (write-line        " :edit_box{label="角度(mm)";key="key2";value="15";}"
  12.                 fn
  13.     )
  14.     (write-line        " :edit_box{label="距离端线长度";key="key3";value="100";}"
  15.                 fn
  16.     )
  17.     (write-line " ok_cancel;" fn)
  18.     (write-line "  }" fn)
  19.     (close fn)
  20.   )
  21.   
  22.   (defun getdata (/ DCLDATA I KEY)
  23.     (setq i 0)
  24.     (repeat 3                                                    ;"key1"到"key5"
  25.       (setq i (1+ i))
  26.       (setq key (strcat "key" (itoa i)))
  27.       (set (read key) (get_tile key))
  28.       (setq DCLData (cons (cons key (eval (read key))) DCLData))
  29.     )
  30.     (Setenv "HHbianban" (VL-PRIN1-TO-STRING DCLData))
  31.   )
  32.   
  33.   (defun setdata (/ DCLDATA X)
  34.     (cond ((setq DCLData (getenv "HHbianban"))
  35.            (setq DCLData (read DCLData))
  36.            (mapcar '(lambda (x) (Set_tile (car x) (cdr x))) DCLData)
  37.           )
  38.     )
  39.   )
  40.   
  41.   (defun do1 (/ ang c data line m m_perp numb1 numb2 numb3 pt pt1 pt2 pt3 pt4 x x1 x2 y_proj y1 y2)
  42.     (setvar "cmdecho" 0)
  43.     (while (setq line (entsel "\n选择直线: "))
  44.       (setq pt (getpoint "\n请指定方向: "))
  45.       (setq data (entget (car line)))
  46.       (setq x1 (cadr (assoc 10 data)) x2 (cadr (assoc 11 data)) y1 (caddr (assoc 10 data)) y2 (caddr (assoc 11 data)))
  47.       
  48.       ;;读取面板数值
  49.       (setq numb1 (atof key1) numb2 (atof key2) numb3 (atof key3))
  50.       
  51.       ;;选择直线为水平线
  52.       (if (= y1 y2)
  53.         (progn
  54.           (princ "\n为水平线")
  55.           (setq ang (/ pi 2))
  56.           (if (< x1 x2)
  57.             (progn
  58.               (setq pt1 (cdr (assoc 10 data))) ; 获取直线的第一个点
  59.               (setq pt2 (cdr (assoc 11 data))) ; 获取直线的第二个点)
  60.             )
  61.             (progn
  62.               (setq pt2 (cdr (assoc 10 data))) ; 获取直线的第一个点
  63.               (setq pt1 (cdr (assoc 11 data))) ; 获取直线的第二个点)
  64.             )
  65.           )
  66.           (if (> (cadr pt) y1)
  67.             (progn
  68.               (princ "\n点在直线上方。")
  69.               (setq pt1 (polar pt1 (* pi (/ 270 180.0)) numb3)) ;远离端线
  70.               (setq pt2 (polar pt2 (* pi (/ 270 180.0)) numb3)) ;远离端线
  71.               (setq pt1 (polar pt1 (* pi (/ 180 180.0)) numb1)) ;边距
  72.               (setq pt2 (polar pt2 (* pi (/ 0 180.0)) numb1)) ;边距
  73.               (setq pt3 (polar pt1 (+ ang (* pi (/ numb2 180.0))) 300)) ;numb2°斜线
  74.               (setq pt4 (polar pt2 (- ang (* pi (/ numb2 180.0))) 300)) ;numb2°斜线
  75.             )
  76.             (progn
  77.               (princ "\n点在直线下方。")
  78.               (setq pt1 (polar pt1 (* pi (/ 90 180.0)) numb3)) ;远离端线
  79.               (setq pt2 (polar pt2 (* pi (/ 90 180.0)) numb3)) ;远离端线
  80.               (setq pt1 (polar pt1 (* pi (/ 180 180.0)) numb1)) ;边距
  81.               (setq pt2 (polar pt2 (* pi (/ 0 180.0)) numb1)) ;边距
  82.               (setq pt3 (polar pt1 (- ang (* pi (/ (+ 180 numb2) 180.0))) 300)) ;numb2°斜线
  83.               (setq pt4 (polar pt2 (+ ang (* pi (/ (+ 180 numb2) 180.0))) 300)) ;numb2°斜线
  84.             )
  85.           )
  86.         )
  87.       )
  88.       
  89.       ;;选择直线为竖直线
  90.       (if (= x1 x2)
  91.         (progn
  92.           (princ "\n为竖直线")
  93.           (setq ang 0)
  94.           (if (< y1 y2)
  95.             (progn
  96.               (setq pt1 (cdr (assoc 10 data))) ; 获取直线的第一个点
  97.               (setq pt2 (cdr (assoc 11 data))) ; 获取直线的第二个点)
  98.             )
  99.             (progn
  100.               (setq pt2 (cdr (assoc 10 data))) ; 获取直线的第一个点
  101.               (setq pt1 (cdr (assoc 11 data))) ; 获取直线的第二个点)
  102.             )
  103.           )
  104.           (if (> (car pt) x1)
  105.             (progn
  106.               (princ "\n点在直线右侧。")
  107.               (setq pt1 (polar pt1 (* pi (/ 180 180.0)) numb3)) ;远离端线
  108.               (setq pt2 (polar pt2 (* pi (/ 180 180.0)) numb3)) ;远离端线
  109.               (setq pt1 (polar pt1 (* pi (/ 270 180.0)) numb1)) ;边距
  110.               (setq pt2 (polar pt2 (* pi (/ 90 180.0)) numb1)) ;边距
  111.               (setq pt3 (polar pt1 (- ang (* pi (/ numb2 180.0))) 300)) ;numb2°斜线
  112.               (setq pt4 (polar pt2 (+ ang (* pi (/ numb2 180.0))) 300)) ;numb2°斜线
  113.             )
  114.             (progn
  115.               (princ "\n点在直线左侧。")
  116.               (setq pt1 (polar pt1 (* pi (/ 0 180.0)) numb3)) ;远离端线
  117.               (setq pt2 (polar pt2 (* pi (/ 0 180.0)) numb3)) ;远离端线
  118.               (setq pt1 (polar pt1 (* pi (/ 270 180.0)) numb1)) ;边距
  119.               (setq pt2 (polar pt2 (* pi (/ 90 180.0)) numb1)) ;边距
  120.               (setq pt3 (polar pt1 (+ ang (* pi (/ (+ 180 numb2) 180.0))) 300)) ;numb2°斜线
  121.               (setq pt4 (polar pt2 (- ang (* pi (/ (+ 180 numb2) 180.0))) 300)) ;numb2°斜线
  122.             )
  123.           )
  124.         )
  125.       )
  126.       
  127.       ;;选择直线为斜线
  128.       (if (and (/= x1 x2) (/= y1 y2))
  129.         (progn
  130.           (princ "\n为斜线")
  131.           (if (< y1 y2)
  132.             (progn
  133.               (setq pt1 (cdr (assoc 10 data))) ; 获取直线的第一个点
  134.               (setq pt2 (cdr (assoc 11 data))) ; 获取直线的第二个点)
  135.             )
  136.             (progn
  137.               (setq pt2 (cdr (assoc 10 data))) ; 获取直线的第一个点
  138.               (setq pt1 (cdr (assoc 11 data))) ; 获取直线的第二个点)
  139.             )
  140.           )
  141.          
  142.           ; 计算斜率 m 和截距 c
  143.           (setq m (/ (- (cadr pt2) (cadr pt1)) (- (car pt2) (car pt1))))
  144.           (setq c (- (cadr pt1) (* m (car pt1))))
  145.          
  146.           ; 计算垂直线的斜率
  147.           (setq m_perp (- (/ 1 m)))
  148.          
  149.           ; 计算角度
  150.           (setq ang (atan m_perp))
  151.          
  152.           ;计算点 P 到直线的垂直投影点的 y 坐标
  153.           (setq x (car pt))
  154.           (setq y_proj (+ (* m x) c))
  155.          
  156.           ;判断点的位置
  157.           (if (> ang 0)
  158.             (if (> (cadr pt) y_proj)
  159.               (progn
  160.                 (princ "\n点在直线上方。")
  161.                 (setq pt1 (polar pt1 (+ ang (* pi (/ 180 180.0))) numb3)) ;远离端线
  162.                 (setq pt2 (polar pt2 (+ ang (* pi (/ 180 180.0))) numb3)) ;远离端线
  163.                 (setq pt1 (polar pt1 (- ang (* pi (/ 90 180.0))) numb1)) ;边距
  164.                 (setq pt2 (polar pt2 (+ ang (* pi (/ 90 180.0))) numb1)) ;边距
  165.                 (setq pt3 (polar pt1 (- ang (* pi (/ numb2 180.0))) 300)) ;numb2°斜线
  166.                 (setq pt4 (polar pt2 (+ ang (* pi (/ numb2 180.0))) 300)) ;numb2°斜线
  167.               )
  168.               (progn
  169.                 (princ "\n点在直线下方。")
  170.                 (setq pt1 (polar pt1 ang numb3)) ;远离端线
  171.                 (setq pt2 (polar pt2 ang numb3)) ;远离端线
  172.                 (setq pt1 (polar pt1 (- ang (* pi (/ 90 180.0))) numb1)) ;边距
  173.                 (setq pt2 (polar pt2 (+ ang (* pi (/ 90 180.0))) numb1)) ;边距
  174.                 (setq pt3 (polar pt1 (+ ang (* pi (/ (+ 180 numb2) 180.0))) 300)) ;numb2°斜线
  175.                 (setq pt4 (polar pt2 (- ang (* pi (/ (+ 180 numb2) 180.0))) 300)) ;numb2°斜线
  176.               )
  177.             )
  178.             (if (> (cadr pt) y_proj)
  179.               (progn
  180.                 (princ "\n点在直线上方。")
  181.                 (setq pt1 (polar pt1 ang numb3)) ;远离端线
  182.                 (setq pt2 (polar pt2 ang numb3)) ;远离端线
  183.                 (setq pt1 (polar pt1 (- ang (* pi (/ 90 180.0))) numb1)) ;边距
  184.                 (setq pt2 (polar pt2 (+ ang (* pi (/ 90 180.0))) numb1)) ;边距
  185.                 (setq pt3 (polar pt1 (+ ang (* pi (/ (+ 180 numb2) 180.0))) 300)) ;numb2°斜线
  186.                 (setq pt4 (polar pt2 (- ang (* pi (/ (+ 180 numb2) 180.0))) 300)) ;numb2°斜线
  187.               )
  188.               (progn
  189.                 (princ "\n点在直线下方。")
  190.                 (setq pt1 (polar pt1 (+ ang (* pi (/ 180 180.0))) numb3)) ;远离端线
  191.                 (setq pt2 (polar pt2 (+ ang (* pi (/ 180 180.0))) numb3)) ;远离端线
  192.                 (setq pt1 (polar pt1 (- ang (* pi (/ 90 180.0))) numb1)) ;边距
  193.                 (setq pt2 (polar pt2 (+ ang (* pi (/ 90 180.0))) numb1)) ;边距
  194.                 (setq pt3 (polar pt1 (- ang (* pi (/ numb2 180.0))) 300)) ;numb2°斜线
  195.                 (setq pt4 (polar pt2 (+ ang (* pi (/ numb2 180.0))) 300)) ;numb2°斜线
  196.               )
  197.             )
  198.           )
  199.         )
  200.       )
  201.       
  202.       (entmakeX (list '(0 . "LINE") (cons 10 pt1) (cons 11 pt2)))
  203.       (entmakeX (list '(0 . "LINE") (cons 10 pt1) (cons 11 pt3)))
  204.       (entmakeX (list '(0 . "LINE") (cons 10 pt2) (cons 11 pt4)))
  205.       (princ "\n~~~~~~~~~~~分割线~~~~~~~~~~~")
  206.     )
  207.     (princ return#)
  208.   )
  209.   
  210.   (dialog)
  211.   (setq dclid (load_dialog fname))
  212.   (new_dialog "HHbianban" dclid)
  213.   (setdata)
  214.   (action_tile "accept" "(getdata)(done_dialog 1)")
  215.   (action_tile "cancel" "(getdata)(done_dialog 0)")
  216.   (setq return# (start_dialog))
  217.   (unload_dialog dclid)
  218.   (vl-file-delete fname)
  219.   (cond ((equal return# 1) (do1)))
  220. )

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

点评

选水平线报错  发表于 2024-9-24 09:46

评分

参与人数 2明经币 +2 收起 理由
cghdy + 1 赞一个!
bssurvey + 1 赞一个!

查看全部评分

发表于 2024-9-24 11:54:12 | 显示全部楼层
本帖最后由 自贡黄明儒 于 2024-9-29 11:57 编辑
Qwer1243 发表于 2024-9-24 11:45
我不会做面板,你要是方便的话可以帮忙更新一下面板,我刚才重新上传了代码,水平和竖直线不会报错了

  1. (defun C:Ban (/ dialog getdata setdata do1 DCLID FN FNAME)
  2.   (defun dialog        ()
  3.     (setq fname (vl-filename-mktemp nil nil ".dcl"))
  4.     (setq fn (open fname "w"))
  5.     (write-line        "HHbianban : dialog{label=\"画边板 黄明儒\";"
  6.                 fn
  7.     )
  8.     (write-line        " :edit_box{label=\"边距 (mm)\";key=\"key1\";value=\"20\";}"
  9.                 fn
  10.     )
  11.     (write-line        " :edit_box{label=\"角度(mm)\";key=\"key2\";value=\"15\";}"
  12.                 fn
  13.     )
  14.     (write-line        " :edit_box{label=\"离端部 倍数\";key=\"key3\";value=\"1.5\";}"
  15.                 fn
  16.     )
  17.     (write-line " ok_cancel;" fn)
  18.     (write-line "  }" fn)
  19.     (close fn)
  20.   )

  21.   (defun getdata (/ DCLDATA I KEY)
  22.     (setq i 0)
  23.     (repeat 3                                                    ;"key1"到"key5"
  24.       (setq i (1+ i))
  25.       (setq key (strcat "key" (itoa i)))
  26.       (set (read key) (get_tile key))
  27.       (setq DCLData (cons (cons key (eval (read key))) DCLData))
  28.     )
  29.     (Setenv "HHbianban" (VL-PRIN1-TO-STRING DCLData))
  30.   )

  31.   (defun setdata (/ DCLDATA X)
  32.     (cond ((setq DCLData (getenv "HHbianban"))
  33.            (setq DCLData (read DCLData))
  34.            (mapcar '(lambda (x) (Set_tile (car x) (cdr x))) DCLData)
  35.           )
  36.     )
  37.   )

  38.    (defun do1 ()
  39.     (ACET-UNDO-BEGIN)                                            ;编组
  40.     (setq e0 (entlast))
  41.     (if        (setq e (entsel "\n 型钢端线:"))
  42.       (progn
  43.         (setq p0 (cadr e))
  44.         (setq obj (vlax-ename->vla-object (car e)))
  45.         (setq key3 (* (distof key3) (vlax-get obj 'length)))
  46.         (setq key3 (VL-PRINC-TO-STRING key3))
  47.         (vl-cmdf "_offset" key3 e pause "")
  48.       )
  49.     )
  50.     ;;如果偏移成功
  51.     (setq e (entlast))
  52.     (if        (not (equal e e0))
  53.       (do2 e)
  54.     )
  55.     (ACET-UNDO-END)
  56.   )


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

  61.   (dialog)
  62.   (setq dclid (load_dialog fname))
  63.   (new_dialog "HHbianban" dclid)
  64.   (setdata)
  65.   (action_tile "accept" "(getdata)(done_dialog 1)")
  66.   (action_tile "cancel" "(getdata)(done_dialog 0)")
  67.   (setq return# (start_dialog))
  68.   (unload_dialog dclid)
  69.   (vl-file-delete fname)
  70.   (cond ((equal return# 1) (do1)))
  71. )

do2就交给你了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
发表于 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)]:
命令: ; 错误: 参数太多
 楼主| 发表于 2024-9-24 10:27:15 | 显示全部楼层
自贡黄明儒 发表于 2024-9-24 10:14
机械行业同行呀,这个不错。以往我都是手画的。
选择角钢端部那条线,每边留20mm,以便于焊接,再沿角钢另 ...

我是钢结构深化的,经常会用到,两边的却是经常预留20mm,是不是规范我也不清楚
发表于 2024-9-24 10:14:19 | 显示全部楼层
机械行业同行呀,这个不错。以往我都是手画的。
选择角钢端部那条线,每边留20mm,以便于焊接,再沿角钢另一边移动一个距离(不知道这个距离有没有规范要求),这样更智能。
发表于 2024-9-24 10:19:26 | 显示全部楼层
这不钢结构嘛, 必须15度吗? 不能自动剪裁
发表于 2024-9-24 10:25:21 | 显示全部楼层
tiancao100 发表于 2024-9-24 10:19
这不钢结构嘛, 必须15度吗? 不能自动剪裁

这个角度应该是个变值,可以取0度。关键楼主点取那条线,到角钢端部,有没有规范要求。
 楼主| 发表于 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度,我就没添加调整参数

弄个界面,适应各种情况

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
 楼主| 发表于 2024-9-24 11:42:50 | 显示全部楼层
我更新了一下代码,可以使用与水平和竖直线了@xyp1964
 楼主| 发表于 2024-9-24 11:45:05 | 显示全部楼层
自贡黄明儒 发表于 2024-9-24 11:23
弄个界面,适应各种情况

我不会做面板,你要是方便的话可以帮忙更新一下面板,我刚才重新上传了代码,水平和竖直线不会报错了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-22 20:04 , Processed in 0.227341 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表