关于坐标偏移
有什么办法,只知道坐标的情况下的多边形,向外偏移,生成的坐标是offset向外偏移得的多边坐标相同效果 本帖最后由 Gu_xl 于 2012-4-1 10:47 编辑两种方法可以得到坐标偏移值,一种是纯数学方法,一种是图形模拟法!
1、纯数学法 (如图所示)
根据图示,由p0 p1 p2以及偏距,很容易计算出偏移点p1‘的坐标,即先计算p0 p1 p2的夹角2a以及夹角平分线的角度,然后根据三角函数关系计算d1,使用polar函数得到p1’坐标。逐一计算点表各顶点的偏移点,即可得到所有偏移坐标!
上述计算是基于点表为逆时针排列的,即p0 p1 p2为逆时针,所以在计算前要先判断点表是否为逆时针,关于点表的逆时针判断,论坛里有相关的帖子,在此不予赘述!
2、图形模拟法
根据点表绘制多段线poly1,利用vla-offset方法,得到偏移后的多段线poly2,判断poly2的长度d2与poly1的长度d1的关系,
d2 > d1, 则是向外偏移
d2 < d1 则是向内偏移
然后逐一取出poly2的顶点坐标!这种方法比较简单,
下面给出第二种方法的示例代码:
**** Hidden Message *****
感谢版主,这确实是好方法,久不来明经了,都不认识人了,以前没见过版主,幸会,前一个方法,我觉得非常好,第二个方法,也想学习一下,不太了解版主为什么要判断
d2 > d1, 则是向外偏移
d2 < d1 则是向内偏移
因为,我没怎么看懂版主的代码,我想听一下版主的意思,现在没有CAD 回复 nameld001 的帖子
d2 > d1, 则是向外偏移
d2 < d1 则是向内偏移
你画一个封闭多边形,分别向内偏移和向外偏移,一看图你就明白了! 感谢Gu_xl 版主分享学习
< 谢谢 ! > Gu_xl 版主
向你致敬 本帖最后由 gufeng 于 2011-11-4 15:05 编辑
今天刚好不想用CAD的偏移 写了个 还有好多情况没有处理呢
;;_测试
(defun c:test (/ DIST ENAME FLAG I PLIST X)
;;_获取线的坐标表
(defun PL_plist (ename / en entl flag vlist pt Elev)
(defun LI_item (n alist)
(cdr (assoc n alist))
)
(defun LI_mitem (Code entl / Lst itm)
(setq Lst '())
(foreach itm entl
(if (= (car itm) Code)
(setq Lst (cons (cdr itm) Lst))
)
)
(if Lst
(reverse Lst)
nil
)
)
(setq
vlist '()
entl(entget ename)
en (LI_item 0 entl)
)
(cond
((= en "LWPOLYLINE")
(setq
vlist '()
Elev(LI_item 38 entl)
)
(foreachpt entl
(if (= (car pt) 10)
(setq vlist (cons (list (cadr pt) (caddr pt) Elev) vlist))
)
)
(setq vlist (reverse vlist))
)
((= en "SPLINE")
(setq vlist (LI_mitem 11 entl))
(if (not vlist)
(setq vlist (LI_mitem 10 entl))
(setq vlist (reverse (reverse vlist)))
)
)
((= en "POLYLINE")
(setq
ename (entnext ename)
entl(entget ename)
en (LI_item 0 entl)
vlist '()
)
(while (= en "VERTEX")
(setq flag (LI_item 70 entl))
(if (and
(zerop (logand flag 1))
(zerop (logand flag 2))
(zerop (logand flag 8))
(/= flag 128)
)
(setq
pt (LI_item 10 entl)
vlist (cons pt vlist)
)
)
(setq
ename (entnext ename)
entl (entget ename)
en (LI_item 0 entl)
)
)
(setq vlist (reverse vlist))
)
((= en "LINE")
(setq vlist (list (LI_item 10 entl) (LI_item 11 entl)))
)
((= en "3DFACE")
(setq vlist (list
(LI_item 10 entl)
(LI_item 11 entl)
(LI_item 12 entl)
(LI_item 13 entl)
)
)
)
)
vlist
)
(setq ename (car (entsel)))
(setq plist (PL_plist ename))
(setq dist 10) ;_偏移的距离
(setq flag nil) ;_内外偏移 外T 内 nil
(setq plist (AT_Pl:Offset plist dist flag))
(setq i 0)
(mapcar '(lambda (x)
(command "text" "j" "m" x dist 0 (itoa (setq i (1+ i))))
)
plist
) ;_绘制点号
(setq i 0)
(command "pline")
(mapcar '(lambda (x)
(command x)
)
plist
) ;_绘制多段线
(command "close")
(princ)
);;_数字计算方法偏移多段线
(defun AT_Pl:Offset (plist dist flag / ANG CWW DIST1 N PT PT1 PT2 PT3 RETURN AT_Pl:GetIsSSZ1 AT_G:Get3PtAng)
;;_获取三点的夹角 也就是P1点逆时针到P3点的夹角
;;_返回弧度值
(defun AT_G:Get3PtAng(p1 p2 p3 / ans a b an)
(setq ans (list (angle p1 p2) (angle p3 p2))
a (apply 'min ans)
b (apply 'max ans)
an(- b a)
)
(if(= a (car ans))
an
(- (* 2 PI) an)
)
)
;;_根据坐标表判断是否顺时针
;;_返回值1:顺时针-1:逆时针 0:不能计算
(defun AT_Pl:GetIsSSZ1 (plist / nverts cnt area tmp pt1 pt2)
(setq
cnt 0
nverts (length plist)
area 0.0
)
(while (< cnt (1- nverts))
(setq
pt1(nth cnt plist)
pt2(nth (1+ cnt) plist)
area (+ area (* (cadr pt1) (car pt2)))
cnt(1+ cnt)
)
)
(setq
pt1(nth (1- nverts) plist)
pt2(nth 0 plist)
area (+ area (* (cadr pt1) (car pt2)))
cnt0
tmp0.0
)
(while (< cnt (1- nverts))
(setq
pt1 (nth cnt plist)
pt2 (nth (1+ cnt) plist)
tmp (+ tmp (* (cadr pt2) (car pt1)))
cnt (1+ cnt)
)
)
(setq
pt1(nth 0 plist)
pt2(nth (1- nverts) plist)
tmp(+ tmp (* (cadr pt1) (car pt2)))
area (* 0.5 (- area tmp))
)
(cond
((< area 0.0) (setq area -1))
((> area 0.0) (setq area 1))
(T (setq area 0))
)
area
)
(setq n 0)
(setq cww (AT_Pl:GetIsSSZ1 plist)) ;_-1逆时针
(setq return '()) ;_返回的坐标表
(foreach i plist
(cond ((= n 0) ;_首点
(setq pt1 (last plist))
(setq pt2 i)
(setq pt3 (nth (1+ n) plist))
)
((= n (1- (length plist))) ;_终点
(setq pt1 (nth (1- n) plist))
(setq pt2 i)
(setq pt3 (car plist))
)
(t
(setq pt1 (nth (1- n) plist))
(setq pt2 i)
(setq pt3 (nth (1+ n) plist))
)
)
(ifflag
(progn
(if (= cww -1)
(progn
(setq ang (AT_G:Get3PtAng pt1 pt2 pt3))
(setq dist1 (/ dist (sin (/ ang 2)))) ;_重新计算polar需要的距离
(setq pt (polar pt2 (+ (angle pt2 pt1) (/ ang 2)) dist1))
)
(progn
(setq ang (AT_G:Get3PtAng pt3 pt2 pt1))
(setq dist1 (/ dist (sin (/ ang 2))))
(setq pt (polar pt2 (+ (angle pt2 pt3) (/ ang 2)) dist1))
)
)
(setq n (1+ n))
)
(progn
(if (= cww -1)
(progn
(setq ang (AT_G:Get3PtAng pt1 pt2 pt3))
(setq dist1 (/ dist (sin (/ ang 2))))
(setq pt (polar pt2 (+ (angle pt1 pt2) (/ ang 2)) dist1))
)
(progn
(setq ang (AT_G:Get3PtAng pt3 pt2 pt1))
(setq dist1 (/ dist (sin (/ ang 2))))
(setq pt (polar pt2 (+ (angle pt3 pt2) (/ ang 2)) dist1))
)
)
(setq n (1+ n))
)
)
(setq return (cons pt return))
)
(reverse return)
)
我也想这样处理,但没有找到好的方法 个别系统偏移飞很远的情况,怎么处理 学习一下