狂刀lxx 发表于 2012-1-6 21:21:47

本帖最后由 狂刀lxx 于 2012-1-7 14:59 编辑

提供一个地6题的简练解答

;|6.【曲线计算】10分已知共面且不相交的一直线和一圆弧,求两个对象之间的最小距离。 |;
(defun tt6 (line arc / A1 A2 CEN D P1 P2 PM) ;; by dreamskylxx 2012.1
(setq line (vlax-ename->vla-object line)
      arc (vlax-ename->vla-object arc))
(setq p1 (vlax-get line 'startpoint)
      p2 (vlax-get line 'endpoint)
      a1 (vlax-get arc 'startpoint)
      a2 (vlax-get arc 'endpoint)
      cen(vlax-get arc 'Center))
(if
    (vlax-invoke line 'IntersectWith arc acExtendNone)
    0.
    (progn
      (setq pm (vlax-curve-getclosestpointto line cen T)
             d (apply 'min (mapcar '(lambda(x y)(distance(vlax-curve-getclosestpointto x y) y))
                           (list arc arc line line)
                           (list p1 p2 a1 a2))))
   (if (vlax-curve-getdistatpoint line pm)
       (min d (distance (vlax-curve-getclosestpointto arc pm) pm))
       d
       )
    )
)
)或者

;; by dreamskylxx 2012.1
(defun tt6 (line arc / A1 A2 CEN D ENT1 P1 P2 PM)
(setq ent1 (entget line)
      p1 (cdr(assoc 10 ent1))
      p2 (cdr(assoc 11 ent1))
      a1 (vlax-curve-getstartpoint arc)
      a2 (vlax-curve-getendpoint arc)
      cen(cdr(assoc 10 (entget arc)))
      pm (vlax-curve-getclosestpointto line cen T)
      d(apply 'min (mapcar '(lambda(x y)(distance(vlax-curve-getclosestpointto x y) y))
                           (list arc arc line line)
                           (list p1 p2 a1 a2))))
(if (vlax-curve-getdistatpoint line pm)
   (min d (distance (vlax-curve-getclosestpointto arc pm) pm))
      d
)
)

;;测试程序
(defun c:tt6 ()
   (setq line (car(entsel "\n 选直线:"))
         arc(car(entsel "\n 选圆弧:")))
   (tt6 line arc)
)
第7题组定义,本人以前有个跟组操作相关的函数收集,连接 http://bbs.mjtd.com/thread-86821-1-1.html
在里面找一个改一下就ok了
GU_XL版主,第7题答案缺函数GXL-MASSOC,无法测试

;;测试:(GPDEl (setq ent (car (entsel "\n选择要删除组的图元:"))))
;; 删除所选物体的所在组定义(支持多重组定义)
(defun gpdel (gpe / el lst a gpdf gplst);;by dreamskylxx 2012.1
(setq el (entget gpe))
(if (setq lst (member '(102 . "{ACAD_REACTORS") el))
    (while (and (setq lst (cdr lst)) (= 330 (car (setq a (car lst)))))
      (if (= "GROUP" (cdr (assoc 0 (setq gpdf (entget (cdr a))))))
      (entdel (cdr(assoc -1 gpdf)))
      )
    )
)
)
第4题相对容易,也没有什么特别的处理方法,略过。
第8题,gu版的动作比较大,相当于把所有的都卸载,再重新加载。
   我提个想法,能不能 用vl-unload-vlx先卸载指定fas或vlx,收集family再 load加载,收集family,两次进行对比。。。



chlh_jd 发表于 2012-1-7 20:08:43

做下第六题,并延伸到空间曲线
(defun c:test
       (/ en1 e en2 fuzz l1 l2 lim l0 d0 p0 p)
;;by GSLS(SS) 2012.1.2
(defun getlength (e)
    (vlax-curve-getDistAtPoint
      e
      (vlax-curve-getendpoint e)
    )
)
(defun f0 (a b / mid rslt)
    (repeat (/ (length a) b)
      (setq mid nil)
      (repeat b
(setq mid (cons (car a) mid)
       a   (cdr a)
)
      )
      (setq rslt (cons (reverse mid) rslt))
    )
    (if a
      (reverse (cons a rslt))
      (reverse rslt)
    )
)
(defun f1 (e p)
    (distance p (vlax-curve-getClosestPointTo e p))
)
(defun f2 (e1 e2 p lim / l0 d0 p0 l)
    (setq l0 (vlax-curve-getDistAtPoint e1 p)
   d0 (f1 e2 p)
   p0 p
   ll0
    )
    (repeat 10
      (setq l (- l lim))
      (if (and (>= l 0) (setq p (vlax-curve-getpointatdist e1 l)))
(if (and (setq d (f1 e2 p))
   (< d d0)
   )
   (setq d0 d
p0 p
   )
)
      )
    )
    (setq l l0)
    (repeat 10
      (setq l (+ l lim))
      (if (and (>= l 0) (setq p (vlax-curve-getpointatdist e1 l)))
(if (and (setq d (f1 e2 p))
   (< d d0)
   )
   (setq d0 d
p0 p
   )
)
      )
    )
    p0
)
(defun f3 (e1 e2 lim / mid)
    (if (not
   (minusp
   (vlax-safearray-get-u-bound
       (vlax-variant-value
(setq mid (vla-IntersectWith
       (vlax-ename->vla-object e1)
       (vlax-ename->vla-object e2)
       lim
   )
)
       )
       1
   )
   )
)
      (list-comp (vlax-safearray->list (vlax-variant-value mid))
   3
      )
    )
)
(setq en1 (car (ss-Nentsel "\nSelect First Curve :"))
en2 (car (ss-Nentsel "\nSelect Second Curve :"))
)
(setq fuzz (getreal "\nType in Accuracy <1e-6> :"))
(or fuzz (setq fuzz 1e-6))
(if (and en1 en2)
    (if (f3 en1 en2 0)
      (princ "\nThe 2 Curves is intersectwithed !")
      (progn
(setq l1 (getlength en1)
       l2 (getlength en2)
)
(if (< l2 l1)
   (setq e   en1
en1 en2
en2 e
l1l2
   )
)
(setq lim (/ l1 (1+ (fix (/ l1 200.))))
       l00.
       d01e308
)
(repeat (fix (/ l1 lim))
   (setq p (vlax-curve-getpointatdist en1 l0))
   (setq d (f1 en2 p))
   (if (< d d0)
   (setq d0 d
    p0 p
   )
   )
   (setq l0 (+ l0 lim))
)
(setq is_go T)
(while (and (> lim fuzz) is_go)
   (setq p (f2 en1 en2 p0 (setq lim (/ lim 10.))))
   (if (equal p p0 fuzz)
   (setq is_go nil
    p0 p
   )
   (setq p0 p)
   )
)
(setq p (vlax-curve-getClosestPointTo en2 p0))
(entmakex (list (cons 0 "LINE")
   (cons 8 "Defpoints")
   (cons 10 p0)
   (cons 11 p)
   (cons 62 1)
    )
)
      )
    )
)
(princ)
)
(defun ss-Nentsel (msg / en en1 pt mat ins mat ent)
(setq en (Nentsel msg))
(if (= (length en) 4)
    (progn
      (setq en1 (car en)
   pt (cadr en)
   mat (caddr en)
   ins (last mat)
   mat (butlast mat)
   mat (ss-getrcsmatrix mat ins)
      )
      (setq ent (entget en1 (list "*")))
      (setq ent (vl-remove (assoc -1 ent) ent))
      (setq en1 (entmakex ent))
      (if en1
(progn
   (setq obj (en2obj en1))
   (vla-TransformBy obj (vlax-tmatrix mat))
   (setq en1 (obj2en obj))
)
      )
      (list en1 pt T)
    )
    (append en (list nil))
)
)
;;; BY GSLS(SS)
;;; 2010-09-29
(defun ss-getrcsmatrix (lst org)
(append
    (mapcar (function (lambda (x y)
   (append x (list y))
      )
   )
   lst
   org
    )
    (list (list 0. 0. 0. 1.))
)
)

byghbcx 发表于 2012-1-9 17:41:17

题目2,可以用直角坐标系求出坐标,qjchen的矩阵算法较好;
题目3,GU_xl 的递归算法较好,但题目为什么限用递归,因要求是3D点计算,复杂点;
题目4,直接替换凸度即可,由于REVCLOUD命令画出的直接是lwpolyline线,对polyline线没作计算;
题目5,对MLINE线的起始点、内弧、外弧计算较复杂,没作计算,只对线型、图层、颜色、坐标点进行计算;
题目6,对直线是否无限长,没作规定,所以只能以一般含端点直线加以计算,分了几种情况加以判断。
(defun c:tt2()
(setq ab (car (entsel "\n请选择AB直线:")))
(setq ab_dxf (entget ab))
(setq a_cor (cdr (assoc 10 ab_dxf))
      b_cor (cdr (assoc 11 ab_dxf))
      len   (distance a_cor b_cor)
      ang   (angle a_cor b_cor))
(setq det_x (* len (cos (+ ang (/ (* pi 89.0) 180.0))))
      det_y (* len (sin (+ ang (/ (* pi 89.0) 180.0))))
)
(setq ptb (list (+ det_x (car a_cor) ) (+ det_y (cadr a_cor) ) (caddr a_cor)))
(setq det_x (- (car a_cor) (car ptb)) det_y (- (cadr a_cor) (cadr ptb)))
(setq pta (list (+ (* 3.5 det_x) (car ptb)) (+ (* 3.5 det_y) (cadr ptb)) (caddr ptb)))
(list pta ptb)
;(command "line" pta ptb "")
)
(defun tt3( lst / lst1 lst2 lst3 d dd ang n)
(setq lst1 (reverse (cdr (reverse lst))))
(setq lst2 (cdr lst) lst3 nil)
(mapcar '(lambda(x y)
      (if (> (setq d (distance x y)) 100)
      (progn
   (setq dd d n 0)
   (while (> dd 100)
   (setq dd (* 0.5 dd))
   )
   (repeat (fix (/ d dd))
   (setq lst3 (cons
    (mapcar '(lambda (a b) (+ (* (/ n (/ d dd)) a) b))
    (mapcar '(lambda (a b) (- a b)) y x)
   x)
    lst3))
   (setq n (1+ n))
   )
   )
      (setq lst3 (cons x lst3))
      )
      )
   lst1 lst2)
(setq lst3 (reverse (cons (last lst2) lst3)))
)
;(tt3 lst)(setq lst (list '(0 0 0) '(199 0 0) '(250 0 0) '(450 600 0) '(1600 1000 1000)))
(defun c:tt4( / dxfcod);云线反向
(setq dxfcod (entget (car (entsel "\n请选择REVCLOUD云线:"))))
(mapcar '(lambda(x) (if (= (car x) 42) (setq dxfcod (subst (cons 42 (- (cdr x))) x dxfcod)))) dxfcod)
(entmod dxfcod)
)
(defun c:tt5();非炸开,重绘MLINE
(setq os (getvar 'osmode))
(setvar 'osmode 0)
(setq en (car (entsel "\n请选择多线:")))
(setq dxfcod (entget en))
(setq mlst (entget (cdr (assoc 340 dxfcod))))
(setvar 'clayer (cdr (assoc 8 dxfcod)))
(if (assoc 48 dxfcod) (setvar 'CELTSCALE (cdr (assoc 48 dxfcod))))
(setq m (cdr (assoc 73 dxfcod)) n 0)
(mapcar '(lambda(x) (if (not (member (car x) '(11 13 41))) (setq dxfcod (vl-remove x dxfcod)))) dxfcod)
(repeat m
    (setq mlst (cdr (member (assoc 49 mlst) mlst)))
    (setvar 'cecolor
   (cond
       ((= (cdr (assoc 62 mlst)) 0) "byblock")
       ((= (cdr (assoc 62 mlst)) 256) "bylayer")
       (t (itoa (cdr (assoc 62 mlst))))
       )
   )
    (setvar 'celtype (cdr (assoc 6 mlst)))
    (setq cod dxfcod)
    (command "_.line")
    (while (assoc 11 cod)
      (setq pt (cdr (assoc 11 cod)))
      (setq cod (cdr (member (assoc 11 cod) cod)))
      (setq v (angle '(0 0 0) (cdr (assoc 13 cod))))
      (repeat n (setq cod (cdr (member (assoc 41 cod) cod))))
      (setq d (cdr (assoc 41 cod)))
      (command (polar pt v d))
      )
    (command "")
    (setq n (+ n 2))
    )
(command "_.erase" en "")
(setvar 'osmode os)
)
(defun c:tt6( / line arc pt1 pt2 minpt maxpt)
(setq line (car (entsel "\n请选择直线:")))
(setq arc (car (entsel "\n请选择圆弧:")))
(setq pt1 (cdr (assoc 10 (entget line))) pt2 (cdr (assoc 11 (entget line))))
(setq ang (angle pt1 pt2))
(command "_.rotate" line arc "" pt1 (- (/ (* ang 180.0) pi)))
(setq pt2 (cdr (assoc 11 (entget line))))
(setq ptc (cdr (assoc 10 (entget arc))) r (cdr (assoc 40 (entget arc))))
(setq st (vla-get-startpoint (vlax-ename->vla-object arc)) et (vla-get-endpoint (vlax-ename->vla-object arc)))
(setq st (vlax-safearray->list (vlax-variant-value st)) et (vlax-safearray->list (vlax-variant-value et)))
(command "_.line" ptc (polar ptc (* 0.5 pi) 100) "")
(setq line1 (entlast))
(setq pt (vla-intersectwith (vlax-ename->vla-object line1) (vlax-ename->vla-object line) acextendthisentity))
(if (safearray-value (vlax-variant-value pt))
    (progn
      (vla-getboundingbox (vlax-ename->vla-object arc) 'minpt 'maxpt)
      (setq minpt (vlax-safearray->list minpt) maxpt (vlax-safearray->list maxpt))
      (setq min_d (min (abs (- (cadr minpt) (cadr pt1))) (abs (- (cadr maxpt) (cadr pt1)))))
      )
    (progn
      (command "_.line" ptc (setq pt0 (if (> (distance pt1 ptc) (distance pt2 ptc)) pt2 pt1)) "")
      (setq line2 (entlast))
      (setq pt# (vla-intersectwith (vlax-ename->vla-object line2) (vlax-ename->vla-object arc) acextendnone))
      (if (safearray-value (vlax-variant-value pt#))
(setq min_d (- (distance pt0 ptc) r))
(setq min_d (min (distance pt0 st) (distance pt0 et)))
)
      )
    )
(command "_.rotate" line arc "" pt1 (/ (* ang 180.0) pi))
(command "_.erase" line1 line2 "")
(princ "\n此直线与圆弧之间的最小距离为:")
(princ min_d)
(princ)
)

byghbcx 发表于 2012-1-11 16:06:15

题目1,先用选择集过滤,得到四边形,或园环多段线,再判断四边形的三个角为90度,即为符合要求的。(defun c:tt1(ss / per ss1 n en dxfcod pts ss2)
(defun per (ap1 ap2 bp1 bp2 / a-> b-> ) ;判断垂直,向量点积为零
(setq a-> (mapcar '- ap1 ap2) b-> (mapcar '- bp1 bp2))
(if (equal (apply '+ (mapcar '* a-> b->)) 0 0.0001) t nil)
)
(command "_.convert" "p" "s" ss "")
(sssetfirst nil ss)
(setq ss1 (ssget ":e" '((0 . "*POLYLINE") (-4 . "<or")
                          (-4 . "<and") (-4 . "=") (90 . 2) (-4 . "=") (40 . 0) (-4 . "=") (41 . 0) (-4 . "=") (42 . 1.0) (-4 . "=") (70 . 1)
                          (-4 . "and>")
                          (-4 . "<and") (-4 . "<or") (-4 . "=") (90 . 4) (-4 . "=") (90 . 5) (-4 . "or>") (-4 . "=") (40 . 0) (-4 . "=") (41 . 0) (-4 . "and>")
                          (-4 . "or>"))))
(setq n 0 ss2 (ssadd))
(repeat (sslength ss1)
    (setq en (ssname ss1 n))
    (setq dxfcod (entget en) pts nil)
    (cond ((= (cdr (assoc 90 dxfcod)) 2) (setq ss2 (ssadd en ss2)));园环
          ((member (cdr (assoc 90 dxfcod)) (list 4 5));四边形多段线
           (mapcar '(lambda(x) (if (= (car x) 10) (setq pts (cons (cdr x) pts)))) dxfcod)
           (if (or (= (cdr (assoc 70 dxfcod)) 1) (equal (car pts) (last pts) 0.0001))
             (if (and (per (car pts) (cadr pts) (car pts) (cadddr pts))
                      (per (cadr pts) (car pts) (cadr pts) (caddr pts))
                      (per (caddr pts) (cadr pts) (caddr pts) (cadddr pts))
                   );三个角为90度
             (setq ss2 (ssadd en ss2))
             )
          )
           )
      )
    (setq n (1+ n))
    )
ss2
)

pzweng 发表于 2012-5-11 11:24:36

学习了

sfzyr 发表于 2012-5-11 12:40:38

看得我都沒信心了

YAOSHIWEI 发表于 2012-5-26 20:07:50

太厉害了

gao051525 发表于 2012-5-26 23:12:47

好难啊,菜鸟路过

chlh_jd 发表于 2012-5-31 02:21:10

本帖最后由 chlh_jd 于 2012-5-31 02:21 编辑

虽然试卷已经公布答案了,个人觉得第1题对于从事建筑结构设计还是比较有帮助的,如选择封闭圆环多义线经常可以用来选择点钢筋(ssget '((0 . "LWPOLYLINE") (90 . 2) (70 . 1) (42 . 1)))选择矩形目前未发现其妙用,对于轻装多义线发下我的代码:;;;SS已知选择集分离出封闭圆环和矩形轻装多义线
(defun test1 (ss / i en ent pts l1 l2)
(setq i -1)
(while (setq en (ssname ss (setq i (1+ i))))
    (setq ent (entget en (list "*")))
    (setq pts (ss-assoc 10 ent))
    (cond ((or
             (and (= (dxf 90 ent) 2)
                  (= (dxf 70 ent) 1)
                  (apply (function =) (cons 1 (ss-assoc 42 ent)))
             )
             (and (= (dxf 90 ent) 3)
                  (= (dxf 70 ent) 0)
                  (equal (car pts) (last pts) 1e-6)
                  (apply (function =) (cons 1 (ss-assoc 42 ent)))
             )
         )
         (setq l1 (cons en l1))
          )
          ((or
             (and (= (dxf 90 ent) 4)
                  (= (dxf 70 ent) 1)
                  (apply (function =) (cons 0 (ss-assoc 42 ent)))
                  (equal (distance (car pts) (caddr pts))
                         (distance (cadr pts) (last pts))
                         1e-6
                  )
             )
             (and (= (dxf 90 ent) 5)
                  (= (dxf 70 ent) 0)
                  (apply (function =) (cons 0 (ss-assoc 42 ent)))
                  (equal (car pts) (last pts) 1e-6)
                  (equal (distance (car pts) (caddr pts))
                         (distance (cadr pts) (last pts))
                         1e-6
                  )
             )
         )
         (setq l2 (cons en l2))
          )
    )
)
(list l1 l2)
)
;;查找组码
(defun dxf (a b)
(cdr (assoc a b))
)
;;批量查找组码
(defun ss-assoc      (a lst / b res)
(while (setq b (assoc a lst))
    (setq lst(cdr (member b lst))
          res (cons (cdr b) res)
    ))(reverse res))

野狼谷/〈M〉 发表于 2012-10-29 15:25:55

好程序,留个脚板印
页: 1 2 [3] 4
查看完整版本: 【活动结束】LISP知识测试问卷--第三期[难度指数[★★★☆]