选择一个多段线后,自动识别出哪一段是直线,哪一自动段是曲线
选择一个多段线后,自动识别出哪一段是直线,哪一自动段是曲线从起点开始,依次分出哪一段是直线?哪一段是圆弧线?
示意图如下:
以下是从百度空间中找到的一个得到多线捌拐点坐标的程序
经测试感觉不错
下载网址如下
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 顶点的凸度是0则是直线,凸度非0则是弧 谢谢您的指点,请教在选中此多线时,如何判断凸度啊?又如何依次区别并得到每一段的凸度?
谢谢您。。。 介绍您先参考下:
http://www.afralisp.net/archive/lisp/Bulges1.htm 先取得顶点坐标,这是必须的
接下来可以依次按坐标计算相邻点的距离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麻烦些,也就是说得分两种情况分别写代码,至于相关的代码论坛里很多,沙发上那个兄弟的就很值得借鉴 本帖最后由 logoin 于 2013-10-30 21:23 编辑
ynhh 发表于 2013-10-30 09:11 static/image/common/back.gif
谢谢您的指点,请教在选中此多线时,如何判断凸度啊?又如何依次区别并得到每一段的凸度?
谢谢您。。。
(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)
)
本帖最后由 自贡黄明儒 于 2013-10-31 09:09 编辑
这个简单,过几天我发一个集成的
;;164.24 [功能] 所击多段线子段是否是直线(返回nil是弧)
;;示例(HH:PickArc (car(setq en(entsel))) (cadr en))
(defun HH:PickArc (curve p / PP)
(setq pp (vlax-curve-getclosestpointto curve (trans p 1 0)))
(setqpp (vlax-curve-getSecondDeriv
curve
(fix (vlax-curve-getparamatpoint curve pp))
)
)
(equal pp '(0.0 0.0 0.0))
) logoin 大师你好:
大师的程序很好,一试就对。但多试则发现有个问题,很多情况下显示的数量会多出一段来,如有4段的多线会显示出5段来啊。最后一段会显示两次,请大师再看看。
黄工你好:
感谢你的热心支持。但你这是判断一整根多线,我所想的是判断一整根多线中的多个段,依次得到那一段是直线,那一段是弧。请你再指导一下啊,谢谢黄工了。 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:图元名
返回值: 子段数量的整数
页:
[1]
2