| 本帖最后由 狂刀lxx 于 2012-1-6 11:54 编辑 
 看了gu_xl的第一题答案,觉得程序写的很长。提出另外一种思路,抛砖引玉。思路是用vlax-curve-getendparam 判断段数,用面积公式判断是否是圆或矩形。
 
  ;| by dreamskylxx-2012.1.6适用lwpolyline,polyline
适用外观闭合(不论最后一段是否是通过CL参数来进行闭合)
圆环适用于两端圆环不一定是半圆
排除多段线重合情况(如看似一个完整圆环,但是实际上有≥3段圆弧段组成)
|;
(defun tt1 (ss / AA C D1 D2 E I L1 L2 O PA SS1 SS2)
  (setq i -1)
  (while (setq e (ssname ss (setq i(1+ i))))
    (setq o (vlax-ename->vla-object e))
    (if(wcmatch (vla-get-objectname o) "*Polyline")
      (setq pa(vlax-curve-getendparam o)))
    (cond
      ((= 2.0 pa)
       (setq c(vla-get-length o)
             aa(vlax-curve-getarea o))
       (if (equal aa (/ (* c c)(* 4. PI)) 1e-6)
         ;;(and (equal aa (/ (* c c)(* 4. PI)) 1e-6)  ;;如果一定要判断是完整的半圆组成
         ;;     (equal c (* 2. (vlax-curve-getdistatparam O 1.)) 1e-6))
         (setq ss1 (cons e ss1)))
       )
      ((= 4.0 pa)
       (setq d1(vlax-curve-getdistatparam O 1.)
             d2(vlax-curve-getdistatparam O 2.)
             l1 d1
             l2 (- d2 d1)
             aa(vlax-curve-getarea o))
       (if (equal aa (* l1 l2) 1e-6)
         (setq ss2 (cons e ss2)))
       )
      (T nil)
    )
  )
  (list ss1 ss2)
)
;;;; 以下是测试程序.
(defun c:ttt();;测试矩形多义线
  (setq ss(ssget)
        fss (tt1 ss))
  (SETQ SSS(SSADD))
  (MAPCAR '(LAMBDA(X)(SSADD X SSS))(caDr fss))
  (sssetfirst NIL SSS)
  )
(defun c:ttt2();;测试圆环多义线
  (setq ss(ssget)
        fss (tt1 ss))
  (SETQ SSS(SSADD))
  (MAPCAR '(LAMBDA(X)(SSADD X SSS))(car fss))
  (sssetfirst NIL SSS)
  )
 
 第2题,其实polar是很好用的,不能用这个函数,难道不能写一个替代函数么?呵呵
 思路是不违反题目要求前提下,写一个替代polar功能的函数,从而使程序代码和结构简洁明了。
 测试代码同 gu_lx中的c:tt2(gu_lx的我测试了一下,是不是忘了缩放比例了?)
 
  ;|2.【几何运算】9分  已知一条端点为A和B的直线,将该直线以A端点为基点旋转89度,再以B端点为基点
  缩放3.5倍,用几何方法求出直线的2个新端点。禁用polar、command、vl-cmdf函数|;
(defun tt2 (LINE ANG SCALE FLAG / ent pt1 pt2 len an pt2x pt1x) ;;by dreamskylxx-2012.1.6
  (setq ent (entget LINE)
        pt1 (cdr(assoc 10 ent))
        pt2 (cdr(assoc 11 ent))
        len (distance pt1 pt2))
  (if (not flag)(setq pt pt1 pt1 pt2 pt2 pt));;对调
  (setq an (angle pt1 pt2)                pt2x(polarx pt1 (+ ang an) len)
        pt1x(polarx pt2x (angle pt2x pt1 ) (* len scale))
        ent (SUBST (cons 10 pt1x)(assoc 10 ent)ent)
        ent (SUBST (cons 11 pt2x)(assoc 11 ent)ent))
  (entmod ent)
)
;; 替代polar函数.
(defun polarx (pt an di)
  (setq x (* di (cos an))
        y (* di (sin an)))
  (mapcar '+ (list x y (nth 2 pt)) pt)
)
第3题, 参照gu_xl的思路,用更紧凑和通俗的格式重写一次,比较纯粹。今晚太晚了,明天有空再玩玩
 
  ;;///////////第3题//////////////////////////////////////////;;
;|3.【点集处理】15分
   已知一个包含若干个三维点的表,若表中相邻两个点之间的距离大于100,则
   在两点之间添加中点,直到表中相邻两个点之间距离小于或等于100。
   限用递归法。
|;
;(TT3x (list '(0 0 0) '(200 0 0) '(250 0 0) '(450 0 0) '(600 0 0)))
;->((0 0 0) (100.0 0.0 0.0) (200 0 0) (250 0 0) (350.0 0.0 0.0) (450 0 0) (525.0 0.0 0.0) (600 0 0)) 
(defun tt3x (pts / p1 p2)
  (if (cdr pts)
    (progn
      (setq p1 (car pts)
            p2 (cadr pts)
      )
      (if (<= (distance p1 p2) 100)
        (cons p1 (tt3x (cdr pts)))
        (tt3x (cons p1 (cons (mapcar '(lambda (a b) (* 0.5 (+ a b))) p1 p2) (cdr pts))))
      )
    )
    (car pts)
  )
)
 
 
 
 
 
 
 |