本帖最后由 Lispboy 于 2013-5-27 23:46 编辑
刚才刚给一个朋友写了由密密麻麻的多段线生成圆弧段多段线的代码,那个代码没用一个循环语句,就拿那个跟你说吧
1、先求出白色多段线的顶点
[pcode=lisp,true]
(setq pts1 (mapcar 'cdr (vl-remove-if-not '(lambda(x)(= (car x) 10)) ed)))
[/pcode]
2、 把 P1 P2 P3 ...P6 组合成 '((p1 p2)(p2 p3)(p3 p4)(p5 p6) (p6 p7))
[pcode=lisp,true]
(setq pts2 (mapcar 'list pts1 (cdr pts1)))
[/pcode]
3、求出每段直线段的中点和法线的直线段, 下图的黄色小短线(单位长度,用到了向量),仔细看。
求每段线的中点
[pcode=lisp,true]
(defun _midp (p1 p2)
(mapcar '(lambda(x)(/ x 2.0))(mapcar '+ p1 p2))
)
(setq pts2 (mapcar '(lambda(x)(_midp (car x)(cadr x))) pts1)
[/pcode]
下面代码是得到小黄线的每段 (中点 法线),PTS1是折线的段((p1 p2)...(p6 p7))
[pcode=lisp,true]
(setq pts2 (mapcar
'(lambda (x)
(list (setq pmid (_midp (setq p1 (car x))
(setq p2 (cadr x))
)
)
(mapcar
'+
pmid
(Mat:ROT90 (MAT:Unitization (mapcar
'-
p2
p1
)
)
)
)
)
)
pts1
)
[/pcode]
3、得到每段的小黄线了,现在我们求所有小黄线的交点
a. 下面代码把每2个小黄线组成 ( (p1 p' p2 p2')....(p2 p2' p3 p3')...),为INTERS函数准备数据,用APPEND是为了去掉一层括号。
[pcode=lisp,true]
(setq pts3 (mapcar 'append pts2 (reverse pts2) )
[/pcode]
b. 用MAPCAR ,APPLY函数,给INTERS函数传递参数,注意有个NIL加到INTERS函数里面。这步代码求完,表PTS4里面就是所有小黄段的交点
(p1 p2 p3 p4....), 就是圆心了。
[pcode=lisp,true]
(setq pts4 (mapcar
'(lambda (x)
(apply
'inters
(reverse (cons nil x))
)
)
pts3
)
)
)
[/pcode]
 - ((88118.5 31585.9) (88118.5 31585.9) (88118.5 31585.9) (88118.5 31585.9)
- (88118.5 31585.9) (88118.5 31585.9))
4、 从每段直线段的中点和圆心画线
[pcode=lisp,true]
(mapcar '(lambda(x y)(command "line" (car x) y "")) pts2 pts4)
[/pcode]
上面所有代码都没有REPEAT,WHILE循环语句,就是MAPCAR实现的,给求交点函数 inters 构造参数的时候用了APPLY
上面的过程就是演示了从一个折线段求圆心的过程。
|