mycad 发表于 2010-2-26 13:44:00

[求助]判断线顺时针还是逆时针提示错误

本帖最后由 作者 于 2010-2-26 14:32:44 编辑 <br /><br /> <p>;;本人刚学习LISP ,请高手指教一下</p><p>下面是mjtd.com的判断“顺时针”还是“反时针”</p><p>;;我的CAD是2002的,使用cad2008也不行</p><p>;;调试出现<strong>“ActiveX 服务器返回错误: 未知名称: Length”</strong>错误提示</p><p>(defun C:test(/ ss fd ang offsetObj plineObj)<br/>&nbsp; (if (setq ss (ssget ":s" '((0 . "*POLYLINE"))));;"LWPOLYLINE"也不行吗<br/>&nbsp;&nbsp; (progn<br/>&nbsp;&nbsp;&nbsp; (setq plineObj (vlax-ename-&gt;vla-object (ssname ss 0)))<br/>&nbsp;&nbsp;&nbsp; (setq fd (vlax-curve-getFirstDeriv plineObj 0.5))<br/>&nbsp;&nbsp;&nbsp; (setq ang (atan (/ (cadr fd) (car fd))))<br/>&nbsp;&nbsp;&nbsp; (setq offsetplineObj (car (vlax-safearray-&gt;list<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (vlax-variant-value<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (vla-offset plineObj 0.0001)))))<br/>&nbsp;&nbsp;&nbsp; (if (&gt; (vla-get-length plineobj) (vla-get-length offsetplineobj))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (princ "\n顺时针.")<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (princ "\n反时针.")<br/>&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp; (vla-delete offsetplineObj)<br/>&nbsp;&nbsp; );progn<br/>&nbsp;&nbsp; (princ "\nNo object selected or object selected is not a polyline.")<br/>&nbsp;);end_if<br/>&nbsp;(princ)<br/>)</p><p></p><p>;;;;经过如下修改也不行吗,奇怪</p><p>(defun C:ta(/ ss fd ang offsetObj plineObj)<br/>&nbsp; (vl-load-com)<br/>&nbsp; (setq ent (car (entsel "\n选取多线:\n")))<br/>&nbsp; (setq PLTYPE (cdr (assoc 0 (entget ent))))<br/>&nbsp; ;;(setq ss (ssget ":s" '((0 . "LWPOLYLINE"))));"LWPOLYLINE"<br/>&nbsp; (if (or (= "POLYLINE" PLTYPE) (= "LWPOLYLINE" PLTYPE))<br/>&nbsp;&nbsp; (progn<br/>&nbsp;&nbsp;&nbsp; ;(setq plineObj (vlax-ename-&gt;vla-object (ssname ss 0)))<br/>&nbsp;&nbsp;&nbsp; (command "lengthen" ent "")<br/>&nbsp;&nbsp;&nbsp; (setq plineObj (vlax-ename-&gt;vla-object ent))<br/>&nbsp;&nbsp;&nbsp; (setq fd (vlax-curve-getFirstDeriv plineObj 0.5))<br/>&nbsp;&nbsp;&nbsp; (setq ang (atan (/ (cadr fd) (car fd))))<br/>&nbsp;&nbsp;&nbsp; (setq offsetplineObj (car (vlax-safearray-&gt;list<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (vlax-variant-value<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (vla-offset plineObj 0.0001)))))<br/>&nbsp;&nbsp;&nbsp; (if (&gt; (vla-get-length plineobj) (vla-get-length offsetplineobj))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (princ "\n顺时针.")<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (princ "\n反时针.")<br/>&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp; (vla-delete offsetplineObj)<br/>&nbsp;&nbsp; );progn<br/>&nbsp;&nbsp; (princ "\nNo object selected or object selected is not a polyline.")<br/>&nbsp;);end_if<br/>&nbsp;(princ)<br/>)<br/></p>

vormittag 发表于 2011-11-2 13:32:55

本帖最后由 vormittag 于 2011-11-3 12:11 编辑

对于平面曲线的顺、逆时针判断可以采用数学的方法。
已知平面三点(xi yi)、(xj yj) 、(xk yk),如果我们对三角形面积的值域取实数,则三角形面积计算公式如下:

其中:当三点以顺时针排列时 A 为负,当三点为逆时针排列时 A 为正。

可以证明:当 (x1 y1)(x2 y2)(x3 y3) ... (xn yn) 为沿折线走向排列的折线顶点时:

为折线围成的多边形(若起终点不重合,则补充终点至起点的直线构成多边形)的面积,且当这n个点顺时针排列时, A 为负,当n点为逆时针排列时 A 为正。

根据这个算法可以得到判断由n个点构成的折线其走向的函数。
完全代码如下:
;;; 按计算三角形oij的倍面积
(defun calo2A (pti ptj)
(- (* (car pti) (cadr ptj)) (* (car ptj) (cadr pti)))
)

;;; 判断多段线是否为逆时针走向,ename图元必须为LWPOLYLINE
(defun clockwisep (ename / ptlist)
(setq ptlist (apply 'append (mapcar '(lambda (x) (if (= 10 (car x)) (list(cdr x)))) (entget ename))))
(>(apply '+ (mapcar 'calo2A (cons (last ptlist)(reverse (cdr (reverse ptlist)))) ptlist))
    0
)
)上面代码对逆时针走向的LWPOLYLINE返回T,共线或顺时针走向返回nil

补充说明一点:对于只有两个顶点的LWPOLYLINE返回值必然是nil,如果是两个顶点的圆弧形式的多段线,再补充一个中点即可,对于三个顶点以上,不论是否含有弧线段,上面的代码均成立。


waterchen 发表于 2010-12-9 12:54:16

(vla-get-length plineobj)中plineobj应该没有length这个属性项吧;(command "lengthen" ent "")中ent是vl物件,这肯定会出错的。

waterchen 发表于 2010-12-9 12:55:10

调试时跟踪一下就知道了。

zzl9105 发表于 2011-11-2 11:14:55

没看懂,谁能帮忙注释一下呀,一个lisp,太多的vla,看帮助,也是迷糊

payforfree 发表于 2011-11-2 21:57:25

哪位大师,能把楼主的程序调试一下。最好能批量的把顺逆时针的多短线用颜色给区分出来。多谢了!

llsheng_73 发表于 2013-11-17 17:18:31

vormittag 发表于 2011-11-2 13:32 static/image/common/back.gif
对于平面曲线的顺、逆时针判断可以采用数学的方法。
已知平面三点(xi yi)、(xj yj) 、(xk yk),如果我们对 ...

这个太经典了!!
毫不客气拿走
学习之。。。

yshf 发表于 2013-11-17 18:13:29

; 二维多段线顺时针转还是逆时针转的判断
; 判断原理:当二维多段线顺时针转时,
;   使用(vla-offset obj 0.001)会使其往内偏移,面积
;   比偏移前小;反之,会往外偏移,面积比偏移前大。
(defun c:test()
    (vl-load-com)
    (while (setq ssa (ssget ":s" '((0 . "LWPOLYLINE"))))
      (setq Obj (vlax-ename->vla-object (ssname ssa 0)))
      (vla-offset obj 0.001)
      (setq obj1 (vlax-ename->vla-object (entlast))
              mj0(vlax-get obj "area")
            mj1(vlax-get obj1 "area")
      )
      (if (> mj0 mj1)
            (princ "\n顺时针")
            (princ "\n逆时针")
      )
      (vla-delete obj1)
    )
    (princ)
)

434939575 发表于 2014-11-8 12:17:44

vormittag 发表于 2011-11-2 13:32 static/image/common/back.gif
对于平面曲线的顺、逆时针判断可以采用数学的方法。
已知平面三点(xi yi)、(xj yj) 、(xk yk),如果我们对 ...

太好了。终于找到了。谢谢。

ltrliu 发表于 2015-5-23 14:55:44

新人学习中
页: [1] 2
查看完整版本: [求助]判断线顺时针还是逆时针提示错误