958620832 发表于 2013-11-16 09:52:49

关于倒角的一个问题

本帖最后由 958620832 于 2013-11-16 11:35 编辑

用chamfer或者FILLET命令来倒角,两条线中只要有一条线是多段线,倒角的同时,两条线就会合并成一条多段线,并且线性、颜色、线宽都统一了。问题就在这,倒角的结果是合并,线性、颜色、线宽统一,而我不希望合并,并且线性、颜色、和线宽都保持原样。请问如何实现?如有谁能写出代码,就更好了

958620832 发表于 2013-11-19 18:07:17

本帖最后由 958620832 于 2013-11-21 08:22 编辑

liu22737 发表于 2013-11-18 16:58 http://bbs.mjtd.com/static/image/common/back.gif
管他有什么要求,直接调用AUTOCAD原始命令啊

(defun c:tt(/ b2 a2)
思路不错,根据你提出的思路,编出来了,也试验成功了。
(defun c:f (/ ent1 ent2 ent3 ent4) ;;;仅适用于直线(LINE)、多段线(POLYLINE和LWPOLYLINE两种)
(setq obj1 (entsel) obj2 (entsel))
(setq e1 (car obj1) e2 (car obj2) p1 (cadr obj1) p2 (cadr obj2))
(setq ent1 (entget e1) ent2 (entget e2) ty1 (cdr (assoc 0 ent1)) ty2 (cdr (assoc 0 ent2)))
(vl-cmdf "chamfer" p1 p2) ;第一步,倒角
(setq e3 (car (nentselp p1)))
(if (or (= ty1 "LWPOLYLINE") (= ty2 "LWPOLYLINE") (= ty1 "POLYLINE") (= ty2 "POLYLINE")) (progn
    (vl-cmdf "BREAK" e3 "int" p1 p2 "int" p1 p2) ;第二步,打断
    (setq e3 (car (nentselp p1)) e4 (car (nentselp p2)))
    (setq ent3 (entget e3) ent4 (entget e4))
    (if (= ty1 "LINE") (progn (vl-cmdf "explode" e3 "") (setq e3 (car (nentselp p1))) (setq ent3 (entget e3))))
    (if (= ty2 "LINE") (progn (vl-cmdf "explode" e4 "") (setq e4 (car (nentselp p2))) (setq ent4 (entget e4))))
    ;第三步,属性还原(ent1还原ent3,ent2还原ent4),还原属性共有颜色(62)、线型(6)、比例(48)三种
    (setq ys1 (if (assoc 62 ent1) (assoc 62 ent1) (cons 62 256)) xx1 (if (assoc 6 ent1) (assoc 6 ent1) (cons 6 "bylayer")))
    (setq ys3 (if (assoc 62 ent3) (assoc 62 ent3)) xx3 (if (assoc 6 ent3) (assoc 6 ent3)))
    (setq ys2 (if (assoc 62 ent2) (assoc 62 ent2) (cons 62 256)) xx2 (if (assoc 6 ent2) (assoc 6 ent2) (cons 6 "bylayer")))
    (setq ys4 (if (assoc 62 ent4) (assoc 62 ent4)) xx4 (if (assoc 6 ent4) (assoc 6 ent4)))
    (setq bl1 (if (assoc 48 ent1) (assoc 48 ent1) (cons 48 1)) bl2 (if (assoc 48 ent2) (assoc 48 ent2) (cons 48 1)))
    (setq bl3 (if (assoc 48 ent3) (assoc 48 ent3)) bl4 (if (assoc 48 ent4) (assoc 48 ent4)))
    (setq ent3 (if ys3 (subst ys1 ys3 ent3) (append ent3 (list ys1))))
    (setq ent3 (if xx3 (subst xx1 xx3 ent3) (append ent3 (list xx1))))
    (setq ent3 (if bl3 (subst bl1 bl3 ent3) (append ent3 (list bl1))))
    (entmod ent3)
    (setq ent4 (if ys4 (subst ys2 ys4 ent4) (append ent4 (list ys2))))
    (setq ent4 (if xx4 (subst xx2 xx4 ent4) (append ent4 (list xx2))))
    (setq ent4 (if bl4 (subst bl2 bl4 ent4) (append ent4 (list bl2))))
    (entmod ent4)))
(princ))

liu22737 发表于 2013-11-16 09:52:50

本帖最后由 liu22737 于 2013-11-19 09:51 编辑

llsheng_73 发表于 2013-11-18 09:00 static/image/common/back.gif
限于水平无法一次性理解你的描述
管他有什么要求,直接调用AUTOCAD原始命令啊

(defun c:tt(/ b2 a2)
(setvar"trimmode" 1)(setvar"filletrad" 0)(setvar"cmdecho"0)(setvar"osmode" 0)
(command"FILLET"
(setq ss1(ssget":S"'((0 . "LINE,LWPOLYLINE,SPLINE,ARC,RAY,XLINE")))
      a1(ssnamex ss1 0)a2(cdr(assoc 0(entget(cadar a1))))p1(cadar(cdddar a1))ss1 ss1)
(setq ss2(ssget":S"'((0 . "LINE,LWPOLYLINE,SPLINE,ARC,RAY,XLINE")))
      b1(ssnamex ss2 0)b2(cdr(assoc 0(entget(cadar b1))))p2(cadar(cdddar b1))ss2 ss2)
)
(if(or(="LWPOLYLINE"a2)(="LWPOLYLINE"b2))(progn
      (vl-cmdf"BREAK"(nentselp(trans p1 0 1))"f""int"(trans p1 0 1)(trans p2 0 1)"int"(trans p1 0 1)(trans p2 0 1))
      (if(not(and(="LWPOLYLINE"a2)(="LWPOLYLINE"b2)))
             (vl-cmdf"EXPLODE"(entlast));还原尾巴属性
             ;;;;还原第二条多义线属性
          )
))
);end
程式不完整,如果两条都是多义线,打断后用ENTLAST还原第二条属性就是了,后面你就自己写吧!

llsheng_73 发表于 2013-11-16 11:19:07

楼主需要的不是直接修剪就可以了么?
还是我理解有误?

llsheng_73 发表于 2013-11-16 11:22:17

本帖最后由 llsheng_73 于 2013-11-16 11:24 编辑

我的思路如下:假设你的线段都是多线段或者直线
先求它们的交点(extend用都延伸),分别求出交点到线段的起点或者止点的距离最近的那个点,将其坐标改为交点坐标(或者对其进行修剪或者延长,比较之下直接修改坐标要好处理些)

llsheng_73 发表于 2013-11-16 12:14:10

本帖最后由 llsheng_73 于 2013-11-16 17:29 编辑

(defun C:trimandextend(/ ss a b c p)
(defun SstoEs(ss / a en lst)
    (if ss(progn(setq a -1)
          (while(setq en(ssname ss(setq a(1+ a))))(setq lst (cons en lst)))))
    lst)
(defun array->list(l / i p)
    (if(>(vlax-safearray-get-u-bound l 1)1)
      (progn
        (setq l(vlax-safearray->list l)i 0)
        (repeat(/(length l)3)
          (setq p (cons(list(nth i l)(nth(+ 1 i)l)(nth (+ 2 i)l))p)
                i(+ 3 i))
          ))
      (setq p '()))
    p)
(setq continue t)
(while continue
(prompt"选择要处理的两条线段右键退出")
(setq ss(sstoes(ssget'((0 . "*line")))))
(if(=(length ss)2)
    (if(setq a(vlax-ename->vla-object(car ss))
             b(vlax-ename->vla-object(cadr ss))
             c(car(array->list(vlax-variant-value(vla-IntersectWith a b 3)))))
      (progn
        (setq p(car(vl-sort(list(vlax-curve-getStartPoint a)(vlax-curve-getEndPoint a))
                           '(lambda (a b)(< (distance c a) (distance c b))))))
        (if(=(vla-get-objectname a)"AcDbLine")
          (entmod(subst(cons 11 c)(cons 11 p)(subst(cons 10 c)(cons 10 p)(entget(vlax-vla-object->ename a)))))
          (entmod(subst(list 10 (car c)(cadr c))(list 10 (car p)(cadr p))(entget(vlax-vla-object->ename a))))
          )
        (setq p(car(vl-sort(list(vlax-curve-getStartPoint b)(vlax-curve-getEndPoint b))
                           '(lambda (a b)(< (distance c a) (distance c b))))))
        (if(=(vla-get-objectname b)"AcDbLine")
          (entmod(subst(cons 11 c)(cons 11 p)(subst(cons 10 c)(cons 10 p)(entget(vlax-vla-object->ename b)))))
          (entmod(subst(list 10 (car c)(cadr c))(list 10 (car p)(cadr p))(entget(vlax-vla-object->ename b))))
          )
        )
      (alert"选择对象没有交点"))
    (if ss(alert"选择对象只能两个")(setq continue nil))
    ))
);;命令可以自己改简单一些以方便你自己使用

郁闷的是不知道浏览器出了什么幺蛾子,传不了附件,自己复制代码吧,虽然会有点乱

958620832 发表于 2013-11-17 17:51:49

本帖最后由 958620832 于 2013-11-17 17:54 编辑

llsheng_73 发表于 2013-11-16 12:14 static/image/common/back.gif
郁闷的是不知道浏览器出了什么幺蛾子,传不了附件,自己复制代码吧,虽然会有点乱
谢谢你的答复,但还不是我真正想要的那样。
我所希望的是,如附图所示。
比如,点击图一中的A点和B点,倒角结果是图二;点击图一中的C点和D点,倒角结果是图三;
点击图一中的A点和C点,倒角结果是图四;点击图一中的B点和D点,倒角结果是图五。
也就是说,倒角的结果跟点击的那一侧有关。
但你所提供的程序,不管点击哪一侧,倒角都只有图二那一种结果。

llsheng_73 发表于 2013-11-17 22:20:43

958620832 发表于 2013-11-17 17:51 static/image/common/back.gif
谢谢你的答复,但还不是我真正想要的那样。
我所希望的是,如附图所示。
比如,点击图一中的A点和B点, ...

这个图怎么不早发出来,那不早就有你要的结果了么?

958620832 发表于 2013-11-17 22:36:33

本帖最后由 958620832 于 2013-11-17 22:37 编辑

llsheng_73 发表于 2013-11-17 22:20 static/image/common/back.gif
这个图怎么不早发出来,那不早就有你要的结果了么?
是我没有表述清楚。之前,倒角我用的都是cad系统本身就有的chamfer或者FILLET命令,但后来发现它的某一方面的功能对我来说有点多余,就是,只要两条线中有一条是多段线,倒角的结果就是将两条线合并为一条多段线,并且颜色、线型、线宽都同一了,我想将这一个功能取消,但其他功能都保留,想找个能替代chamfer或者FILLET命令的程序,只是本人编写lisp程序水平有限,始终都编不出来,于是就求助于各位高手。

llsheng_73 发表于 2013-11-17 22:37:53

本帖最后由 llsheng_73 于 2013-11-17 23:05 编辑

958620832 发表于 2013-11-17 22:36 static/image/common/back.gif
是我没有表述清楚。之前,倒角我用的都是cad系统本身就有的chamfer或者FILLET命令,但后来发现它的某一方 ...

(defun C:trimandextend(/ a0 b0 c p a1 b1 continue)
(defun array->list(l / i p)
    (if(>(vlax-safearray-get-u-bound l 1)1)
      (progn
        (setq l(vlax-safearray->list l)i 0)
        (repeat(/(length l)3)
          (setq p (cons(list(nth i l)(nth(+ 1 i)l)(nth (+ 2 i)l))p)
                i(+ 3 i))
          ))
      (setq p '()))
    p)
(setq continue t)
(while continue
    (setq a0(entsel"要处理倒角的第一条线(注意要保留哪端点那一边)"))
    (setq b0(entsel"要处理倒角的第二条线(注意要保留哪端点那一边)"))
    (if(and a0 b0"AcDbPolyline")
      (if(setq a1(vlax-ename->vla-object(car a0))
             b1(vlax-ename->vla-object(car b0))
             c(car(array->list(vlax-variant-value(vla-IntersectWith a1 b1 3)))))
        (if(and(vl-string-search"line"(vla-get-objectname a1))(vl-string-search"line"(vla-get-objectname b1)))
          (progn
          (setq p(car(vl-sort(list(vlax-curve-getStartPoint a1)(vlax-curve-getEndPoint a1))
                             '(lambda (a b)(>(/(distance(cadr a0)a)(distance a c)) (/(distance(cadr a0)b)(distance b c)))))))
          
          (if(=(vla-get-objectname a1)"AcDbLine")
          (entmod(subst(cons 11 c)(cons 11 p)(subst(cons 10 c)(cons 10 p)(entget(vlax-vla-object->ename a1)))))
          (entmod(subst(list 10 (car c)(cadr c))(list 10 (car p)(cadr p))(entget(vlax-vla-object->ename a1))))
          )
          (setq p(car(vl-sort(list(vlax-curve-getStartPoint b1)(vlax-curve-getEndPoint b1))
                             '(lambda (a b)(>(/(distance(cadr b0)a)(distance a c)) (/(distance(cadr b0)b)(distance b c)))))))
          (if(=(vla-get-objectname b1)"AcDbLine")
          (entmod(subst(cons 11 c)(cons 11 p)(subst(cons 10 c)(cons 10 p)(entget(vlax-vla-object->ename b1)))))
          (entmod(subst(list 10 (car c)(cadr c))(list 10 (car p)(cadr p))(entget(vlax-vla-object->ename b1))))
          )
          )(alert"选择了非直线或者多线段对象")
          )
        (alert"选择对象没有交点"))
      (setq continue nil)
      ))
);;;命令可以自己改简单一些以方便你自己使用

复制这个吧,破浏览器还是没法挂附件,另外提示信息你可以自己改简单一些,如果之前没有相交的会被延伸,对象可以是直线或者多线段.一个小玩意弄得这会又改了好几次总算可以对楼主交差了

958620832 发表于 2013-11-18 08:33:06

本帖最后由 958620832 于 2013-11-18 08:35 编辑

llsheng_73 发表于 2013-11-17 22:37 static/image/common/back.gif
复制这个吧,破浏览器还是没法挂附件,另外提示信息你可以自己改简单一些,如果之前没有相交的会被延 ...
非常感谢你的帮助,但还是不够完善啊。
问题在于,多段线不一定是直的,还可以是折的。对于只有两个顶点的多段线或者直线,你的程序很好用,但对于三个或三个以上顶点的多段线,你的程序就不太适用了。如附图所示,图中的黄线是有四个顶点的多段线,白线是直线,也可以是只有两个顶点的多段线,点击图一中的A点和B点,我所想要的结果是图二,而你程序的结果是图三。
chamfer或者FILLET命令都很管用,但它的某一方面的功能对我来说有点多余,就是,只要两条线中有一条是多段线,倒角的结果就是将两条线合并为一条多段线,并且颜色、线型、线宽都同一了,我想将这一个功能取消,但其他功能都保留。
页: [1] 2 3
查看完整版本: 关于倒角的一个问题