Re: [問題] Autocad中polyline的圖元串列資料
※ 引述《ggg888 (g8)》之銘言:
: 請問版上高手
: 我畫一了一條polyline
: 其中還包括有圓孤的部份
: 取出這條線的串列資料後
: 發現關於圓孤的部份的資料為
: (10 409.77 199.567) (40 . 0.0) (41 . 0.0) (42 . -0.466828)
: 10應該是起點,請問42.代表的是什麼樣的資料呢?
: 由於我想寫一個程式,可以在這條polyline中每隔20m插入一個block
: 所以必須計算每段線段,包括孤長的長度,
: 藉此算出每個插入點的座標
: 請問各位有那些方法可以達到呢?
如果要寫程式可以用下式:
先畫一條聚合線或雲形線,長度超過20
(setq dist 20)
(setq Curve-obj(vlax-ename->vla-object(car(entsel))))
(setq Prm (vlax-curve-getParamAtDist Curve-obj dist))
(setq Pt (vlax-curve-getPointAtParam Curve-obj Prm))
如此就可以取得20m處的座標值 Pt
當然這樣的功能用內建的 measure可以達成,
所以要寫程式就要有其必要性,不然這樣好了,再求出該點法向斜率:
(setq Dri (vlax-curve-getFirstDeriv curve-obj Prm))
(setq Ang (+ (* pi 0.5) (angle '(0 0 0) Dri)))
如此就可以取得20m處的法向角度 Ang,可以調整插入圖塊的角度,
但這有什麼用嗎?用 measure 插入圖塊用對齊不就好了!
寫程式的用處在於:不等距分段、依里程標記
1. 可以不等距的分段,這點 measure 就很麻煩,
應該要支援 3@200, 2@150 表示式,試著設計輸入迴圈如下:
(defun GetList(/ ls tmp tmpls @)
(setq ls '())
(while (/= "" (setq tmp (getstring "hint:3@200=(200,200,200):")))
(setq tmpls '() ls
(append ls
(if (setq @ (vl-string-search "@" tmp))
(repeat(atoi tmp)
(setq tmpls (append tmpls (list (substr tmp (+ 2 @))))))
(list tmp) ) ) ) );_ eo while
(mapcar 'ATOF ls)) ;_eo GetList
(setq SegList (GetList))
如此可得各分段距離串列 SegList (ex: 200.0 200.0 200.0 150.0 150.0 300.0)
再寫個小程式來累計串列:
(defun CumulativeList(oList / ls add nList)
(setq ls 0.0 nList '())
(foreach add oList(setq ls(+ ls add)nList(append nList(list ls)))))
(setq CumList (CumulativeList SegList))
如此可得累進距離串列 CumList (ex: 200.0 400.0 600.0 750.0 900.0 1200.0)
2. 可以在每個分段依其里程長度作動態標示(ex:Sec.2 ,Len=200.0, Loc=400.),
下面以畫垂線示範一個簡單完整的程式,也可以改為插入圖塊就更簡單:
(vl-load-com)
(defun c:meas()
(setq MSpace(vla-get-ModelSpace(vla-get-ActiveDocument(vlax-get-acad-object)))
SegList (ms:GetList)
CumList (ms:CumulativeList SegList)
Offset (getreal "Offset distance:")
Extend (getreal "Extend length:")
Curve-obj(vlax-ename->vla-object(car(entsel)))
n 0)
(foreach Loc CumList
(setq
Prm (vlax-curve-getParamAtDist curve-obj Loc)
Pt1 (vlax-curve-getPointAtParam curve-obj Prm)
Dri (vlax-curve-getFirstDeriv curve-obj Prm)
Ang (+ (* pi 0.5) (angle '(0 0 0) Dri))
Pt2 (polar Pt1 Ang Offset)
Pt1 (polar Pt2 Ang Extend)
Str (strcat " Sec."(itoa n)", Len="(rtos(nth n SegList))", Loc="(rtos Loc))
Obj (vla-AddLine MSpace (vlax-3d-point Pt2) (vlax-3d-point Pt1))
Obj (vla-AddText MSpace Str (vlax-3d-point Pt2) (getvar "textsize"))
n (1+ n) )
(vla-put-Rotation Obj (+ Ang pi)) ));_eo meas
(defun ms:GetList(/ ls tmp tmpls @)
(setq ls '())
(while (/= "" (setq tmp (getstring "hint:3@200=(200,200,200):")))
(setq tmpls '() ls
(append ls
(if (setq @ (vl-string-search "@" tmp))
(repeat(atoi tmp)
(setq tmpls (append tmpls (list (substr tmp (+ 2 @))))))
(list tmp) ) ) ) );_ eo while
(mapcar 'ATOF ls)) ;_eo GetList
(defun ms:CumulativeList(oList / ls add nList)
(setq ls 0.0 nList '())
(foreach add oList(setq ls(+ ls add)nList(append nList(list ls)))))
執行範例:
先畫一條spline, 其長度約1000以上, 執行 meas
輸入分段長度:0 3@200 2@150 <enter>
輸入Offset:-100
輸入extend:200
選取曲線:
OK
目前這是個非常陽春的曲線分段程式,並無設定起點功能,
只要加入check指定起點是否為曲線起點就可以了,
如果為否就令 CumList = 曲線長 - CumList 即可,
不過 Visual Lisp 有一點很奇怪的地方,
就是 ActiveX 裡面 polyline 有 length property,
可以用 (setq Curve-Len(vla-get-length Curve-obj)) 取得。
但是 Spline 卻沒有 length property,
故 spline 的曲線長必須改為下式:
(setq Curve-Len(vlax-curve-getDistAtParam curve-obj
(vlax-curve-getEndParam curve-obj)))
這點真是夠了,連 spline 的曲線長都和 ls 指令不太相同。
--
小弟初學 Lisp 若有寫錯請見諒!
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 118.169.200.130
※ 編輯: suny999 來自: 118.169.200.130 (05/29 14:59)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 3 之 3 篇):
Cad_Cae 近期熱門文章
PTT數位生活區 即時熱門文章