明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3435|回复: 12

[已解答] 选择一个多段线后,自动识别出哪一段是直线,哪一自动段是曲线

[复制链接]
发表于 2013-10-29 13:11:47 | 显示全部楼层 |阅读模式
选择一个多段线后,自动识别出哪一段是直线,哪一自动段是曲线
从起点开始,依次分出哪一段是直线?哪一段是圆弧线?
示意图如下:

本帖子中包含更多资源

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

x
"觉得好,就打赏"
还没有人打赏,支持一下
 楼主| 发表于 2013-10-29 13:15:06 | 显示全部楼层
以下是从百度空间中找到的一个得到多线捌拐点坐标的程序
经测试感觉不错

下载网址如下
http://hi.baidu.com/123523058/item/0aa2ec7cac7bf2356e29f6d0

;;;测试如下
(setq ss (ssget))
(setq i 0)
(sslength ss)
(setq ssn (ssname ss i))
(ayGetPLineVTX SSN)
得到如下坐标值,即直线和曲线,所有两端点的坐标
((2668.14 381.333) (2812.11 555.782) (2849.35 452.435) (2814.6 366.451) (2754.22 306.074))

;;;返回多段线(*POLYLINE)的所有顶点坐标 获取 LWPOLYLINE 对象所有顶点坐标


;;;****************************************************
;;; No.23-4 返回多段线(*POLYLINE)的所有顶点坐标 函数
;;;****************************************************
(defun ayGetPLineVTX (EntName1 / Obj1 vtx vtxlst PtsList i)
(cond
   ((= (cdr (assoc 0 (entget EntName1))) "LWPOLYLINE")
   (setq PtsList (ayGetLWPolyLineVTX EntName1))
   );end_switch
   ((= (cdr (assoc 0 (entget EntName1))) "POLYLINE")
   (setq PtsList (ayGetPolyLineVTX EntName1))
   );end_switch
);end_cond
(setq PtsList PtsList)
);end_defun

;;;-----------------------------------------------
;;; No.23-4-1 获取 LWPOLYLINE 对象所有顶点坐标   
;;;-----------------------------------------------
(defun ayGetLWPolyLineVTX (EntName1 / Obj1 vtx vtxlst PtsList i)
(vl-load-com)
(setq Obj1 (vlax-ename->vla-object EntName1))
(setq vtx (vla-get-Coordinates Obj1))
(setq vtxLst (vlax-safearray->list (vlax-variant-value vtx)))
(setq i 0)
(setq PtsList nil)
(repeat (/ (length vtxLst) 2)
   (setq PtsList (append PtsList (list (list (nth i vtxLst) (nth (1+ i) vtxLst)))))
   (setq i (+ i 2))
);end_repeat
(setq PtsList PtsList)
);end_defun

;;;---------------------------------------------
;;; No.23-4-2 获取 POLYLINE 对象所有顶点坐标   
;;;---------------------------------------------
(Defun ayGetPolyLineVTX (LwPolyEntName / entData1 entName1 pel ptp wpl wpll plp par ct
                          pen rl pn clk pt al gx bj np xc gg rr cp retList)
(setq entName1 LwPolyEntName)
(setq retList nil)
(setq entData1 (entget entName1))
(if (= "POLYLINE" (Cdr (Assoc 0 entData1)))
   (progn
    (setq pel entData1             ;取出对象表.
         ptp (Cdr (Assoc 70 pel)) ;取出结束片段型.
         wpl '()                  ;自建的点位数表.
       wpll '()
       entName1 (EntNext entName1)
       pen entName1
    );end_setq
    (While (/= "SEQEND" (Cdr (Assoc 0 (entget pen))));如果没束.
     (setq pel (entget pen)               ;取得顶点对象数据表.
           plp (Cdr (Assoc 10 pel))       ;取出控制点点位.
           par (Cdr (Assoc 42 pel))       ;取出弓弦比.
           wpl (Cons (List plp par) wpl) ;将数据加到WPL表中.
        wpll (cons plp wpll)
     );end_setq
     (setq pen (EntNext pen));搜索下一个对象.
    );end_while
    (setq wpll (Reverse wpll))

    ;以下代码暂时没有用!
    (setq ct (If (= 0 (Cadr (Car wpl))) "直线片段封闭" "弧片段封闭"))
    (setq wpl (Cons (Last wpl) wpl);加入封闭点.
        wpl (Reverse wpl)        ;整理WPL表.
         rl (Length wpl)
         pn 0
    );end_setq
    (setq clk (If (Or (= 0 ptp) (= 128 ptp)) "开口" "封闭"))
    (Repeat (1- rl)          ;逐点分析.
     (setq al (Nth pn wpl) ;取出点数据表.
           pt (Car al)      ;取出点位.
     );end_setq
     (If (And (/= 0.0 (Cadr al)) (Nth pn wpl)) ;如果是断.
       (Progn (setq gx (Cadr al)               ;取出弓比.
                    bj (* (ATAN (ABS gx)) 4)   ;计算包角.
                    np (Car (Nth (1+ pn) wpl)) ;取出下一点位.
                    xc (* 0.5 (Distance pt np));半弦长计算.
                    gg (* gx xc)               ;弓高计算.
                    rr (/ (+ (* xc xc)(* gg gg)) (* 2 gg))
               );end_setq
               (setq cp (Polar pt (setq pa (Angle pt np)) xc)
                     cp (Polar cp (+ pa (* 0.5 PI)) (- rr gg))
               );end_setq
       );end_progn
     );end_if
      (setq pn (1+ pn))
    );end_repeat
   
    (setq retList wpll)
   );end_progn
);end_if
);end_defun
发表于 2013-10-29 21:21:34 | 显示全部楼层
顶点的凸度是0则是直线,凸度非0则是弧

点评

谢谢您的指点,请教在选中此多线时,如何判断凸度啊?又如何依次区别并得到每一段的凸度? 谢谢您。。。  发表于 2013-10-30 09:09
 楼主| 发表于 2013-10-30 09:11:12 | 显示全部楼层
谢谢您的指点,请教在选中此多线时,如何判断凸度啊?又如何依次区别并得到每一段的凸度?
谢谢您。。。
发表于 2013-10-30 09:29:17 | 显示全部楼层
发表于 2013-10-30 10:26:59 | 显示全部楼层
先取得顶点坐标,这是必须的
接下来可以依次按坐标计算相邻点的距离D1 (setq D1(distance p1 p2))和根据点在线段上的长度计算出它们在曲线上的长度D2 (setq D2(abs(- (vlax-curve-getDistAtPoint curve-obj p1)(vlax-curve-getDistAtPoint curve-obj p1)))如果可以忽略计算误差,直线段上D1和D2相等,弧线段一般不会相等,当然也有相等的时候存在,不过这个时候是可以被当成直线段的。  
      当然,如果不允许上边的误差,那只能去得到每一个的组码42的值来判断,唯一对于POLYLINE,它的顶点以及顶点上的参数的获取都比LWPOLYLINE麻烦些,也就是说得分两种情况分别写代码,至于相关的代码论坛里很多,沙发上那个兄弟的就很值得借鉴
发表于 2013-10-30 21:19:06 | 显示全部楼层
本帖最后由 logoin 于 2013-10-30 21:23 编辑
ynhh 发表于 2013-10-30 09:11
谢谢您的指点,请教在选中此多线时,如何判断凸度啊?又如何依次区别并得到每一段的凸度?
谢谢您。。。

(defun c:ff()
(vl-load-com)
(if (and (setq plEnt(car (entsel))) (= (cdr (assoc 0 (entget plEnt))) "LWPOLYLINE" ))
  (progn
    (setq plObj (vlax-ename->vla-object plEnt))
    (setq index 0)
    (setq plptNum (/ (vl-list-length (vlax-safearray->list (vlax-variant-value (vla-get-Coordinates plObj)))) 2))
    (while (< index plptNum)
      (setq plBulge (vla-getbulge plObj index))
      (if (= plBulge 0)
        (print (strcat "第 " (itoa (1+ index )) " 段是直线"))
        (print (strcat "第 " (itoa (1+ index )) " 段是弧"))
      )
      (setq index (1+ index))
    )
  )
  )
  (princ)
  )

点评

大师的程序很好,一试就对。但多试则发现有个问题,很多情况下显示的数量会多出一段来,如有4段的多线会显示出5段来啊。最后一段会显示两次,请大师再看看。  发表于 2013-10-31 12:16
发表于 2013-10-30 21:49:12 来自手机 | 显示全部楼层
本帖最后由 自贡黄明儒 于 2013-10-31 09:09 编辑

这个简单,过几天我发一个集成的
  1. ;;164.24 [功能] 所击多段线子段是否是直线(返回nil是弧)
  2. ;;示例(HH:PickArc (car(setq en(entsel))) (cadr en))
  3. (defun HH:PickArc (curve p / PP)
  4.   (setq pp (vlax-curve-getclosestpointto curve (trans p 1 0)))
  5.   (setq  pp (vlax-curve-getSecondDeriv
  6.        curve
  7.        (fix (vlax-curve-getparamatpoint curve pp))
  8.      )
  9.   )
  10.   (equal pp '(0.0 0.0 0.0))
  11. )

点评

黄工请看 11 楼,感觉你说反了哈。。有些没整理的程序不知对你有用吗。  发表于 2013-10-31 14:09
logoin 大师你好:我参考以下10楼的程序,在你程序中加入个 1- 感觉就对了,请你验证指点。  发表于 2013-10-31 12:40
黄工你好:感谢你的热心支持。但你这是判断一整根多线,我所想的是判断一整根多线中的多个段,依次得到那一段是直线,那一段是弧。请你再指导一下啊,谢谢黄工了。  发表于 2013-10-31 12:23
 楼主| 发表于 2013-10-31 12:23:50 | 显示全部楼层
logoin 大师你好:
大师的程序很好,一试就对。但多试则发现有个问题,很多情况下显示的数量会多出一段来,如有4段的多线会显示出5段来啊。最后一段会显示两次,请大师再看看。

黄工你好:
感谢你的热心支持。但你这是判断一整根多线,我所想的是判断一整根多线中的多个段,依次得到那一段是直线,那一段是弧。请你再指导一下啊,谢谢黄工了。
 楼主| 发表于 2013-10-31 12:40:08 | 显示全部楼层
logoin 大师你好:我参考以下程序,在你程序中加入个 1- 感觉就对了,请你验证指点。

numbersofseg 返回多段线子段的数量
   语法:

(numbersofseg SSN);在此返回段数

   说明:

返回多段线子段的数量

   函数内容:

(defun numbersofseg (ename)  

   (setq obj (vlax-ename->vla-object ename))

   (setq plist (vlax-safearray->list

   (vlax-variant-value

     (vla-get-coordinates obj))))

   (1- (/ (length plist) 2))

)
   参数:
ename:图元名
   返回值: 子段数量的整数

点评

封闭的才减一  发表于 2013-10-31 13:07
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-23 14:59 , Processed in 0.200081 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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