zzyong00 发表于 2014-9-1 23:24:49

反转多线段源码,求指点


;;反转PL线-----zzyong00

(defun C:RevPL (/ SS)
(princ "\n反转PL线,假设只有直线段")
(if (setq SS (ssget '((0 . "LWPOLYLINE"))))
    (progn
      (setq I 0)
      (repeat (sslength SS)
        (setq ENT (entget (ssname SS I)))
        ;;得到顶点表
        (setq LST_PT '())
        (foreach N ENT
          (if (= (car N) 10)
          (setq LST_PT (cons N LST_PT))
          )
        )

        (foreach I '(10)
          (setq
          ENT        (vl-remove-if
                  '(lambda (N) (= (car N) I))
                  ENT
                )
          )
        )
        (setq ENT (append ENT LST_PT))
        (entmod ENT)


        ;;
        (setq I (1+ I))
      )                                        ;repeat
    )                                        ;progn
    (princ ">>>图内没有二维多段线")
)                                        ;if
(princ)
)


反转多线段,和autocad的命令reverse 相差甚远,请教一下,有圆弧的,该如何反转呢?


Andyhon 发表于 2014-9-2 08:55:05

Ref:
http://bbs.mjtd.com/thread-48118-1-1.html
...

ll_j 发表于 2014-9-2 09:00:10

本帖最后由 ll_j 于 2014-9-2 09:17 编辑

很久以前搞过,现在已经找不到了,依稀记得点思路,不妨说给你试试。
有圆弧的多段线,实际上就是有一个凸度的42组码,而多段线的最后一点的凸度是表达“趋势”的,没有实际用途,所以可以忽略,同时,形状相同方向相反的圆弧,凸度也是反的,基于这个道理,可以通过点和凸度配对的方法反向多段线,具体做法如下:
取多段线的顶点10和凸度42构成的表,反向,把最前的42组码(原是最后)调整到最后,把所有不为0的凸度组码取负值,加上实体表头和210组码对原实体表进行替换。

zzyong00 发表于 2014-9-2 22:06:11

本帖最后由 zzyong00 于 2014-9-2 22:45 编辑

ll_j 发表于 2014-9-2 09:00 static/image/common/back.gif
很久以前搞过,现在已经找不到了,依稀记得点思路,不妨说给你试试。
有圆弧的多段线,实际上就是有一个凸 ...


谢谢 ll_j,按你说的,我重新修改了代码
另一问题:210组码需要改吗?我发现reverse也没修改这个组码的内容,这个组码改与不改有什么区别吗?

zzyong00 发表于 2014-9-2 22:19:08

本帖最后由 zzyong00 于 2014-9-2 22:44 编辑

有错误,圆弧反转后变直线了;;反转PL线-----zzyong00

(defun C:RevPL (/ SS)
(princ "\n反转PL线,假设只有直线段")
(if (setq SS (ssget '((0 . "LWPOLYLINE"))))
    (progn
      (setq I 0)
      (repeat (sslength SS)
(setq ENT (entget (ssname SS I)))
;;得到顶点表
(setq LST_PT '())
;;得到凸度表
(setq LST_Bulge '())
          ;取多段线的顶点10和凸度42构成的表,反向,把最前的42组码(原是最后)调整到最后,把所有不为0的凸度组码取负值,加上实体表头和210组码对原实体表进行替换。
(foreach N ENT
    (if (= (car N) 10)
      (setq LST_PT (cons N LST_PT))
    )
    (if (= (car N) 42)
      (progn
      (if (not (eq (cdr N) 0.0))
    (setq
      LST_Bulge (cons (cons 42 (- (cdr N))) LST_Bulge)
    )
    (setq LST_Bulge (cons N LST_Bulge))
      )
      )
    )
)
(foreach L '(10)
    (setq
      ENT(vl-remove-if
      '(lambda (N) (= (car N) L))
      ENT
    )
    )
)
(foreach L '(42)
    (setq
      ENT(vl-remove-if
      '(lambda (N) (= (car N) L))
      ENT
    )
    )
)
(setq ENT (append ENT LST_PT LST_Bulge))
(entmod ENT)


;;
(setq I (1+ I))
      )          ;repeat
    )          ;progn
    (princ ">>>图内没有二维多段线")
)          ;if
(princ)
)

ivde 发表于 2014-9-2 22:20:56

已有reverse命令

zzyong00 发表于 2014-9-2 22:46:24

ivde 发表于 2014-9-2 22:20 static/image/common/back.gif
已有reverse命令

我知道啊!...............

zzyong00 发表于 2014-9-2 23:29:16

;;反转PL线-----zzyong00

(defun C:RevPL (/ SS)
(princ "\n反转PL线,假设只有直线段")
(if (setq SS (ssget '((0 . "LWPOLYLINE"))))
    (progn
      (setq I 0)
      (repeat (sslength SS)
        (setq ENT (entget (ssname SS I)))
        ;;得到顶点表
        (setq LST_PT '())
        ;;得到凸度表
        (setq LST_Bulge '())
                                        ;取多段线的顶点10和凸度42构成的表,反向,把最前的42组码(原是最后)调整到最后,把所有不为0的凸度组码取负值,加上实体表头和210组码对原实体表进行替换。
        (setq J 0)
        (foreach N ENT
          (if (= (car N) 10)
          (setq LST_PT (cons N LST_PT))
          )
          (if (not (= J 0))
          (if        (= (car N) 42)
              (progn
                (if (not (eq (cdr N) 0.0))
                  (setq
                  LST_Bulge (cons (cons 42 (- (cdr N))) LST_Bulge)
                  )
                  (setq LST_Bulge (cons N LST_Bulge))
                )
              )
          )
          )
          (setq J (1+ J))
        )
        (setq LST_Bulge (append LST_Bulge '((42 . 0.0))))

        (foreach L '(10)
          (setq
          ENT        (vl-remove-if
                  '(lambda (N) (= (car N) L))
                  ENT
                )
          )
        )
        (foreach L '(42)
          (setq
          ENT        (vl-remove-if
                  '(lambda (N) (= (car N) L))
                  ENT
                )
          )
        )
        (setq ENT (append ENT LST_PT LST_Bulge))
        (entmod ENT)
        ;(entmake ent)

        ;;
        (setq I (1+ I))
      )                                        ;repeat
    )                                        ;progn
    (princ ">>>图内没有二维多段线")
)                                        ;if
(princ)
)再改,还是有问题!圆弧变直线了。。

ivde 发表于 2014-9-3 09:56:26

zzyong00 发表于 2014-9-2 23:29 static/image/common/back.gif
再改,还是有问题!圆弧变直线了。。

http://bbs.xdcad.net/forum.php?mod=redirect&goto=findpost&ptid=518918&pid=2557172

ll_j 发表于 2014-9-3 10:15:31

zzyong00 发表于 2014-9-2 23:29 static/image/common/back.gif
再改,还是有问题!圆弧变直线了。。

很久不动了,动起来还有点困难,凑了一段框架,支持宽度,你看看:
(defun c:tt()
(setq en(entsel)
      et(entget (car en))
      es(vl-remove-if '(lambda(x)(member (car x) '(10 40 41 42 91 210))) et) ;实体头
      ee(assoc 210 et)         ;实体尾,拉伸方向,保证在空间的轻多段线不至于变形
      em(vl-remove-if-not '(lambda(x)(member (car x) '(10 40 41 42))) et) ;顶点、宽度、凸度
)
(setq nem(cdddr (reverse em))
      nem(mapcar
             '(lambda(x)
                (cond
                  ((= (car x) 40)   ;首尾宽度转换
                   (cons 41 (cdr x))
                  )
                  ((= (car x) 41)
                   (cons 40 (cdr x))
                  )
                  ((= (car x) 42)   ;凸度反转
                   (cons 42 (- (cdr x)))
                  )
                  (t x)
                )
            )
             nem
         )
)
(setq et (append es nem (list ee)))
(entmod et)
)
页: [1] 2
查看完整版本: 反转多线段源码,求指点