明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 15542|回复: 53

[源码] 直线偏移连动~偏移后修改与其相接触的直线

    [复制链接]
发表于 2014-5-7 18:23:20 | 显示全部楼层 |阅读模式
有时候需要对直线组成的“矩形”某一条边进行修改,可以选择 STRETCH命令,也可以选择offset偏移。但是对于斜向的平行四边形用stretch的时候会改变斜线的角度,(不修改UCS snapang的情况).而用偏移则需要修改偏移后的直线与原直线的关系,使其保持平行四边形关系,为了解决这个问题,所以编写此代码。
====================================

========================================
代码
  1. (defun sk_load_com()
  2. ;;;组码值提取(sk_dxf 图元名 组码)
  3. (defun sk_dxf(en code)
  4.     (if(and(=(type en) 'ENAME)(= (type code) 'INT))
  5.       (cdr(assoc code (entget en))))
  6.   )
  7. ;;;=========================

  8. ;;;(sk_entmod 图元名 组码 新值 强制模式)
  9. (defun sk_entmod (en code new mode / e)
  10.   (if (and (= (type en) 'ENAME)
  11.      (= (type code) 'INT)
  12.      new)
  13.     (progn
  14.       (setq e(entget en))
  15.       (if (assoc code e)(entmod(subst(cons code new)(assoc code e)e))
  16.   (if mode (entmod(reverse(cons(cons code new)(reverse e)))) nil))      
  17.       )
  18.     )
  19.   )
  20. ;;;=========================

  21. ;;;计算cp到p1 p2的垂足点
  22. (defun PerToLine  (cp p1 p2 / norm)
  23.   (setq        norm (mapcar '- p2 p1)
  24.         p1   (trans p1 0 norm)
  25.         cp   (trans cp 0 norm)
  26.         )
  27.   (trans (list (car p1) (cadr p1) (caddr cp)) norm 0)
  28.   )
  29. ;;;=========================

  30. ;;;三点共线
  31. (defun ColinearP  (p1 p2 p3)
  32.     (
  33.      (lambda (a b c)
  34.        (or
  35.          (equal (+ a b) c 1e-8)
  36.          (equal (+ b c) a 1e-8)
  37.          (equal (+ c a) b 1e-8)
  38.          )
  39.        )
  40.       (distance p1 p2)
  41.       (distance p2 p3)
  42.       (distance p1 p3)
  43.       )
  44.     )
  45. ;;;=========================

  46. ;;高亮图元或选择集
  47. (defun sk_highlight (ss flag / i en)
  48.   (if (= (type ss) 'PICKSET)
  49.     (progn
  50.       (setq i -1)
  51.       (repeat(sslength ss)
  52.   (setq en(ssname ss (setq i (1+ i))))
  53.   (redraw en (if flag 3 4))
  54.   )
  55.       )
  56.     )
  57.   (if(= (type ss) 'ENAME)(redraw ss (if flag 3 4)))
  58.   )
  59. ;;;==========================
  60.   (princ)
  61.   )

  62. (defun c:oo(/ ANG1 CPT EN ENT0 IP12 MODCODE NEW1 newp1 newp2 NEW2  OF_DIST1 P0 P1 P2 P3 P4 SS SS1
  63.       ANG2  PX1 PX2 PX3 PX4)
  64.   (sk_load_com)
  65.   (if(setq of_dist1(getdist (strcat "\n输入偏移距离["(if of_dist (rtos of_dist) "0")"]:")))(setq of_dist of_dist1))
  66.   (if (setq ss(ssget":E:S" '((0 . "line"))))
  67.     (progn
  68.       (setq sk_cmd(getvar 'cmdecho))
  69.       (setvar 'cmdecho 0)
  70.       (setq ent0 (ssname ss 0)
  71.       p1 (sk_dxf ent0 10)
  72.       p2 (sk_dxf ent0 11)
  73.       ang2(angle p1 p2)
  74.       px1(polar p1 (+ ang2 (* 0.5 pi)) of_dist)
  75.       px2(polar p2 (+ ang2 (* 0.5 pi)) of_dist)
  76.       px3(polar p1 (+ ang2 (* 1.5 pi)) of_dist)
  77.       px4(polar p2 (+ ang2 (* 1.5 pi)) of_dist)
  78.       )
  79.       (command "_.zoom" p1 p2)
  80.       (setq ss1(ssget "_c" p1 p2 '((0 . "line"))))
  81.       (command "_.zoom" "p")
  82.       (grdraw px1 px2 6 3)
  83.       (grdraw px3 px4 6 3)
  84.       (sk_highlight ss1 t)      
  85.       (if (setq p0(getpoint  "\n指定偏移方向:"))
  86.   (progn
  87.     (sk_highlight ss1 nil)
  88.     (setq ss1(ssdel ent0 ss1))
  89.     (setq cpt(PerToLine p0 p1 p2 )
  90.     ang1(angle cpt p0)
  91.     new1(polar p1 ang1 of_dist)
  92.     new2(polar p2 ang1 of_dist)
  93.     )
  94.     (while(setq en(ssname ss1 0))
  95.       (setq p3(sk_dxf en 10)
  96.       p4(sk_dxf en 11)      
  97.       modcode nil
  98.       )
  99.       (if (or (equal p3 p1 1e-8)        
  100.         (equal p4 p1 1e-8)
  101.         (ColinearP p1 p3 p4)
  102.         )
  103.         (setq newp1(inters new1 new2 p3 p4 nil))
  104.         )
  105.       (if(or (equal p3 p2 1e-8)
  106.        (equal p4 p2 1e-8)
  107.        (ColinearP p2 p3 p4))
  108.         (setq newp2(inters new1 new2 p3 p4 nil)))
  109.       (if (ColinearP p3 p1 p2)(setq modcode 10))
  110.       (if (ColinearP p4 p1 p2)(setq modcode 11))
  111.       (if modcode
  112.         (progn
  113.     (setq ip12(inters new1 new2 p3 p4 nil))
  114.     (sk_entmod en modcode ip12 nil)))
  115.       (setq ss1(ssdel en ss1))
  116.       )
  117.      (sk_entmod ent0 10 (if newp1 newp1 new1) nil)
  118.     (sk_entmod ent0 11 (if newp2 newp2 new2) nil)   
  119.     )
  120.   (progn
  121.     (princ "\n未指定方向点!")
  122.     (sk_highlight ss1 nil)
  123.     )
  124.   )
  125.       (if sk_cmd (setvar 'cmdecho sk_cmd))
  126.       )
  127.     )
  128.   (redraw)
  129.   (princ)
  130.   )
  131. (princ)



本帖子中包含更多资源

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

x

点评

E大很给力,但直线在布局里不能偏移连动,只能回到模型空间,有点不方便,如果完善就更便捷了,直线和多段线如果都能在布局或模型空间都可以,共用一个程序就更爽。期待中  发表于 2020-4-19 07:28

评分

参与人数 10明经币 +12 金钱 +10 收起 理由
masterlong + 1 受这个程序启发做了自己用的偏移拉伸,超爽.
crazylsp + 2 神马都是浮云
伪书虫86 + 1 很给力!
langjs + 2 很给力!
liuhaixin88 + 1 赞一个!
自贡黄明儒 + 1 赞一个!
q3_2006 + 1 很给力!
xyp1964 + 1 赞一个!
林霄云 + 1 + 10 很厉害
lucas_3333 + 1 赞一个! E大重出江湖,可喜可贺!

查看全部评分

"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2020-11-21 16:00:25 | 显示全部楼层
edata 发表于 2014-5-9 18:09
LWPOLYLINE线单边偏移关联(仅多段线)

非常完美啦  能不能再优化成 连续执行   把重复的输入偏移距离给优化掉
发表于 2022-4-21 18:56:02 | 显示全部楼层
受这个程序启发做了自己用的偏移拉伸
超爽
现在才发现
这个帖子当时我居然没有回复和评分?
必须补上
发表于 2018-4-24 11:26:05 | 显示全部楼层
谢谢E大,这个功能不起眼,但是却是非常实用的
发表于 2014-5-7 20:10:52 | 显示全部楼层
大师这个实用。偏移+修剪+延伸。三合一。学习了。
发表于 2014-5-7 21:36:09 | 显示全部楼层
我的CAD2014,没反应啊。
发表于 2014-5-7 21:56:16 | 显示全部楼层
  1. (command "_.zoom" p1 p2)
  2.       (setq ss1(ssget "_c" p1 p2 '((0 . "line"))))
  3.       (command "_.zoom" "p")
点32个赞
发表于 2014-5-8 08:21:49 | 显示全部楼层
哦,习惯多段线了。没看程序啊,用直线就ok了。
发表于 2014-5-8 08:43:40 | 显示全部楼层
这个实用。偏移+修剪+延伸和在一起了,牛哇
发表于 2014-5-9 09:45:41 | 显示全部楼层
对多义线不起作用
发表于 2014-5-9 11:10:55 | 显示全部楼层
楼主高人,以你为榜样!
发表于 2014-5-9 11:45:11 | 显示全部楼层
太厉害了~~~
 楼主| 发表于 2014-5-9 18:09:18 | 显示全部楼层
LWPOLYLINE线单边偏移关联(仅多段线)
  1. (defun c:tt(/ ANG1 ANG2 CPT ENT ENT1 INDEXMAX INDEXMAX1+ INDEXMAX2 INDEXMIN INDEXMIN1 INDEXMIN1- IPT1 IPT2 IS_CLOSED NEW1 NEW2 OBJ  P0 P1 P11 P2 P21 PPX PX SK_COORDS VB_NEW1 VB_NEW4 )
  2.   ;;;组码值提取(sk_dxf 图元名 组码)
  3. (defun sk_dxf(en code)
  4.     (if(and(=(type en) 'ENAME)(= (type code) 'INT))
  5.       (cdr(assoc code (entget en))))
  6.   )
  7. ;;;计算cp到p1 p2的垂足点
  8. (defun PerToLine  (cp p1 p2 / norm)
  9.   (setq        norm (mapcar '- p2 p1)
  10.         p1   (trans p1 0 norm)
  11.         cp   (trans cp 0 norm)
  12.         )
  13.   (trans (list (car p1) (cadr p1) (caddr cp)) norm 0)
  14.   )
  15.   ;;;;;主程序
  16.   (if(setq of_dist1(getdist (strcat "\n输入偏移距离["(if of_dist (rtos of_dist) "0")"]:")))(setq of_dist of_dist1))
  17.   (if(and (and(setq ent1(entsel "\n选择线:"))(or (= (sk_dxf (car ent1) 0 ) "LWPOLYLINE")(= (sk_dxf (car ent1) 0 ) "LINE")))
  18.           (car (list t(redraw (car ent1) 3)))
  19.     (setq p0(getpoint "\n指定偏移方向:")))
  20.     (if(= (sk_dxf (car ent1) 0 ) "LWPOLYLINE")
  21.     (progn
  22.       (setq ent(car ent1)
  23.             px(cadr ent1)
  24.             obj(vlax-ename->vla-object (car ent1)))
  25.       (setq is_closed (sk_dxf ent 70)
  26.             sk_Coords (sk_dxf ent 90))      
  27.       (setq ppx(vlax-curve-getClosestPointTo obj px)
  28.             indexmin1(fix (vlax-curve-getParamAtPoint obj ppx))
  29.             indexmax2(1+ indexmin1)
  30.             indexmin(min indexmin1 indexmax2)
  31.             indexmax(max indexmin1 indexmax2)
  32.             )
  33.       
  34.       (if(and (= indexmin (1- sk_Coords))(= indexmax sk_Coords))
  35.         (setq indexmin1- (1- indexmin )             
  36.               indexmax 0             
  37.               indexmax1+ 1)
  38.         (if (and (= indexmin 0)(/= indexmax (1- sk_Coords)))
  39.           (setq indexmin1- (1- sk_Coords)
  40.                 indexmax1+ (1+ indexmax ))
  41.           (if (= indexmax (1- sk_Coords))
  42.             (setq indexmax1+  0 indexmin1- (1- indexmin))
  43.             (setq indexmin1- (1- indexmin)
  44.                   indexmax1+ (1+ indexmax )))))
  45.       (setq p1(vlax-safearray->list(vlax-variant-value(vla-get-Coordinate obj indexmin)))
  46.             p2(vlax-safearray->list(vlax-variant-value(vla-get-Coordinate obj indexmax)))
  47.             p11(vlax-safearray->list(vlax-variant-value(vla-get-Coordinate obj indexmin1-)))
  48.             p21(vlax-safearray->list(vlax-variant-value(vla-get-Coordinate obj indexmax1+))))
  49.       (setq cpt (PerToLine p0 p1 p2)
  50.             ang1(angle cpt p0)
  51.             ang2(angle p1 p2)
  52.             new1(polar p1 ang1 of_dist)
  53.             new2(polar p2 ang1 of_dist)
  54.             ipt1(inters new1 new2 p1 p11 nil)
  55.             ipt2(inters new1 new2 p2 p21 nil)   
  56.             )
  57.       (if(and (= is_closed 0) (= indexmin 0) )
  58.         (setq ipt1 new1))
  59.       (if(and (= is_closed 0) (= indexmax (1- sk_Coords)) )
  60.         (setq ipt2 new2))
  61.       (setq vb_new1(vlax-safearray-fill(vlax-make-safearray vlax-vbdouble '(0 . 1)) (list(car ipt1)(cadr ipt1)))
  62.             vb_new4(vlax-safearray-fill(vlax-make-safearray vlax-vbdouble '(0 . 1)) (list(car ipt2)(cadr ipt2))))
  63.       (vla-put-Coordinate obj indexmin  vb_new1)
  64.       (vla-put-Coordinate obj indexmax  vb_new4)
  65.       )
  66.       ;;直线偏移部分
  67.       )
  68.     (princ "\n未选择对象")
  69.     )
  70. (if ent1 (redraw (car ent1) 4))
  71.   (princ)
  72.   )

评分

参与人数 3明经币 +3 金钱 +30 收起 理由
kwok + 1 很给力!
lucas_3333 + 1 很给力!
llsheng_73 + 1 + 30 这个很历害的说

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-25 07:15 , Processed in 0.178376 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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