本帖最后由 llsheng_73 于 2014-12-10 22:23 编辑
今天看到这个帖子请高手写个.不用command由点表求偏移指定距离后的点表.
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=100362&fromuid=202795 所以写了这个程序,想了一下,其实不难实现,首先明确需要我们计算什么,怎么计算,于是运行了几下OFFSET命令。直接偏移多线段,再把多线断炸开了一个个偏移,于是它真的不难了,不就相当于先给各段作一个平等线,再把它们延长出去相交?
平行线对应的两个端点可以用(POLAR p ang distance)来计算出来,延长到相交也有个(inters pt1 pt2 pt3 pt4 [onseg])可以直接算出来,那么只差怎么设置循环和一些必要判断了 。唯一要处理的是考虑点表所代表的多线段是否闭合,因为这会影响第一点和最后一点的结果。
由于处理对象是一个点表,所以也不用考虑曲线段的计算了,希望高人们弄出可以考虑曲线段的来,同时希望大家对其中的算法进行必要的优化,在此先行谢过
同时,大家想到了程序中没考虑的问题又确实可以处理或者有必要考虑的也多提宝贵意见哈
- (defun offsetpt(pt d flag / Pldir delselfinter fx m n pi2 d1 p1 p0 p q0 q2 q22 q1 q pt1 pt2);|falg nil闭合点表,T不闭合它;d<0向内>0向外(假定它有内外)
- pt内少于2个点坐标时不处理,直接返回原表,两个点时以前进方向右边为正(和VLA-OFFSET一样)|;
- (defun Pldir(pts)
- (<(apply'+(mapcar'(lambda(x y)(-(*(car x)(cadr y))(*(car y)(cadr x))))pts(append(cdr pts)(list(car pts)))))0));defun
- (defun delselfinter(p / m n i j p1 p2 p3 q);;by Llsheng_73
- (setq m 0 n(-(length p)3))
- (while(< m n)
- (setq p1(nth m p)p2(nth(setq m(1+ m))p)i(1+ m))
- (foreach p3(vl-remove(last p)(cdrnlst i p))
- (if(setq i(1+(vl-position p3 p)) q(INTERS p1 p2 p3(nth i p)))
- (setq p(append(midlstnm 1 m p)(list q)(cdrnlst i p))
- n(-(length p)3)))))
- p);defun
- (setq m(length pt)fx(if(> m 2)(PlDir pt))pt(if fx(reverse pt)pt)
- d1(abs d)
- pi15(*(if(> d 0)1 -1)(* pi 1.5))
- pt2(mapcar'(lambda(y x z)
- (if(setq ang1(+(angle y x)pi15)
- ang2(+(angle x z)pi15)
- q(inters(polar y ang1 d1)(polar x ang1 d1)(polar x ang2 d1)(polar z ang2 d1)nil))
- q(polar x ang2 d1)))(append(list(last pt))pt)pt(cdr(append pt(list(car pt))))))
- (delselfinter(cond((< m 2)pt)
- ((= m 2)(list(polar(car pt)ang1 d1)(polar(last pt)ang1 d1)))
- (flag(cons(polar(car pt)(+(angle(car pt)(cadr pt))pi15)d1)
- (reverse(cons(polar(last pt)(+(angle(cadr(reverse pt))(last pt))pi15)d1)(cdr(reverse pt2))))))
- (t pt2))))
是不是发错地方的,本来想发到源码那的,结果没太注意,如果真发错了并影响版规的话,请版主帮忙移过去哈
最初忘了点不够三个的情况以及不少于三个时方向性的问题,导致有时按定义该往外的它往内,所以又加上了方向的判断处理因为改了一个判断点在点表代表的线内外而导致到处都乱了,现在修改好了,如果有之前复制代码的,对不起了,只能重新复制去才能用哦
其实只有两个点的时候没必要调用这个程序来处理,自己两句(POLAR...)就搞定了,所以我也不管2个点的时候它到底往哪边的了反正我自己碰到只有两个点也不会调用它的
|