lemonbox 发表于 2006-4-13 14:01:00

请教一个关于凸包的问题!

<P>通过参考wkai的凸包程序用lisp实现了求多条pline的凸包</P>
<P>但是当pline中包含曲线,且在边缘处时,就会出现曲线和凸包交叉的问题,因为我的凸包没有考虑出现曲线的情况,现在需要改进这个凸包程序,请问如何才能在出现曲线的地方将凸包也变成曲线呢???</P>UploadFile/2006-4/200641313596793.jpg

lemonbox 发表于 2006-4-13 16:12:00

<P>贴一下程序代码,小弟我刚学lisp不久,现在遇到问题,希望各位高手帮帮忙啊~~</P>
<P>&nbsp;</P>
<P>(vl-load-com)</P>
<P>;;表通用复合排序函数<BR>;;功能&nbsp;&nbsp; :对表进行复合排序<BR>;;参数lst:需要被排序的表<BR>;;sortlst:排序命令序列表<BR>;;返回值 :排序后的表<BR>;;<BR>;;示例:(XDL-SORT '(0 2 3 7 8 5 7 ) '&gt;)<BR>;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 从大到小排序<BR>;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---&gt;&gt;(8 7 5 3 2 0)<BR>;;&nbsp;&nbsp;&nbsp;&nbsp; (XDL-SORT '((0 1)(1 0)(9 6)(9 5)(5 9)(6 9)(7 8)(8 7)) '(0 &gt;))<BR>;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第0项从大到小排序<BR>;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---&gt;&gt;((9 6) (9 5) (8 7) (7 8) (6 9) (5 9) (1 0) (0 1))<BR>;;&nbsp;&nbsp;&nbsp;&nbsp; (XDL-SORT '((0 1)(1 0)(9 6)(9 5)(5 9)(6 9)(7 8)(8 7)) '((0 &gt;)( 1 &lt;)))<BR>;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第0项从大到小第1项从小到大排序;;<BR>;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---&gt;&gt;((9 5) (9 6) (8 7) (7 8) (6 9) (5 9) (1 0) (0 1))<BR>;;&nbsp;&nbsp;&nbsp;&nbsp; (XDL-SORT '((0 1)(1 0)(9 6)(9 5)(5 9)(6 9)(7 8)(8 7)) '(( 1 &lt;)(0 &gt;)))<BR>;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第1项从小到大第0项从大到小排序<BR>;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---&gt;&gt;((1 0) (0 1) (9 5) (9 6) (8 7) (7 8) (6 9) (5 9))<BR>(defun XDL-SORT(lst sortlst / n)<BR>&nbsp; (if (listp sortlst)<BR>&nbsp;&nbsp;&nbsp; (if&nbsp;(listp (car sortlst))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq sortlst (reverse sortlst))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq sortlst (list sortlst))<BR>&nbsp;&nbsp;&nbsp; )<BR>&nbsp;&nbsp;&nbsp; (setq sortlst (list (list nil sortlst)))<BR>&nbsp; )<BR>&nbsp; (foreach n sortlst<BR>&nbsp;&nbsp;&nbsp; (setq lst (vl-sort lst '(lambda (s1 s2)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (apply (cadr n) (list (if (car n) (nth&nbsp; (car n) s1)s1)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (if (car n) (nth&nbsp; (car n) s2)s2))))))<BR>&nbsp;&nbsp;&nbsp; )<BR>&nbsp; )</P>
<P>;;删除表相同元素<BR>;;pts:表&nbsp; fuzz:精度 <BR>(defun lst-remove-dups(pts fuzz / pt x) <BR>(cond ((=(length pts)1) pts) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (t(setq pt(car pts)) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (cons pt(vl-remove-if '(lambda(x)(equal pt x fuzz)) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (lst-remove-dups(cdr pts)fuzz)) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ) <BR>&nbsp;&nbsp;&nbsp;&nbsp; )) <BR>)</P>
<P><BR>;;取与pt的角度与an差最小的距离最远的点<BR>(defun XD_convex_hull_sort_an(pt an ls / re)<BR>&nbsp; (setq re (mapcar '(lambda(x) (list (rem (+ (* 2 pi)(- (angle pt x) an))(* 2 pi))(distance pt x) x)) ls))<BR>&nbsp;&nbsp;&nbsp; (setq re (XDL-SORT re '((0 &lt;)(1 &gt;))))<BR>&nbsp; (last(car re))<BR>)</P>
<P><BR>;;获得包含点表的凸包点表 <BR>;;Graham扫描法<BR>;;参数lst:坐标点表<BR>;;返回值:凸包点表(逆时针)<BR>(defun XD_convex_hull (lst / re tblst AN BG RESULT)<BR>&nbsp; ;;按与pt的角度对点表排序<BR>&nbsp; (setq lst (lst-remove-dups lst 0))&nbsp; <BR>&nbsp; (setq lst (XDL-SORT lst '((0 &lt;)(1 &lt;))));;按XY增排序<BR>&nbsp; (setq&nbsp;bg (car lst)<BR>&nbsp;an (/ pi -2)<BR>&nbsp; )<BR>&nbsp; (setq tblst (list bg))<BR>&nbsp; (while<BR>&nbsp;&nbsp;&nbsp; (and (&gt; (length lst) 2)<BR>&nbsp; (not (and (&gt; (length tblst) 1) (= (car tblst) (last tblst)))<BR>&nbsp; )<BR>&nbsp;&nbsp;&nbsp; )<BR>&nbsp;&nbsp;&nbsp;&nbsp; (setq result (XD_convex_hull_sort_an (car tblst) an (vl-remove (car tblst) lst)))<BR>&nbsp;&nbsp;&nbsp;&nbsp; (setq an (angle (car tblst) result))<BR>&nbsp;&nbsp;&nbsp;&nbsp; (setq tblst (cons result tblst))<BR>&nbsp; )<BR>&nbsp; tblst<BR>)</P>
<P>;;获得pline的所有点集</P>
<P>(defun GetPlinePts( name / ents pts)<BR>&nbsp; (setq ents (entget name))<BR>&nbsp; (while (setq ents (member (assoc 10 ents) ents))<BR>&nbsp;&nbsp;&nbsp; (setq pts (append pts (list (cdar ents))))<BR>&nbsp;&nbsp;&nbsp; (setq ents (cdr ents))<BR>&nbsp; )<BR>&nbsp; pts<BR>)</P>
<P><BR>;;测试:<BR>(defun c:tt(/ lst re tblst ss n)<BR>&nbsp; (command "undo" "be")<BR>&nbsp; (setq ss (ssget '((0 . "LWPOLYLINE"))))<BR>&nbsp; (setq slenall (sslength ss) index 0)<BR>&nbsp; (while (&lt; index slenall)<BR>&nbsp;&nbsp;&nbsp; (setq name (ssname ss index) index (1+ index))<BR>&nbsp;&nbsp;&nbsp; (setq lst (append lst (GetPlinePts name))) <BR>&nbsp; )<BR>&nbsp; (setq tblst (XD_convex_hull lst))<BR>&nbsp; (command "._pline" )<BR>&nbsp; (foreach n tblst<BR>&nbsp;&nbsp;&nbsp; (command "non" n)<BR>&nbsp;&nbsp;&nbsp; )<BR>&nbsp; (command)<BR>&nbsp; (command "undo" "e")<BR>&nbsp; (print tblst)<BR>&nbsp; (princ)<BR>&nbsp; <BR>&nbsp; )</P>

尘缘一生 发表于 2022-3-7 18:42:29

lemonbox 发表于 2006-4-13 16:12
贴一下程序代码,小弟我刚学lisp不久,现在遇到问题,希望各位高手帮帮忙啊~~
&nbsp;
(vl-load-com)

顶起来。。。。
页: [1]
查看完整版本: 请教一个关于凸包的问题!