⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 最小距离点对.lsp

📁 计算几何中的几种lisp语言的算法
💻 LSP
字号:
(defun C:te ();;(/ olderr en errmsg oldmode oce sl ss t0 ptlist pp pp1)
  ;;定义错误函数和预处理
  (setvar "errno" 0)
  (setq olderr *error*)
  (defun *error* (msg)
    (setq en (getvar "errno"))
    (setq errmsg (strcat "errno=" (itoa en) "\nError:" msg))
    (alert errmsg)
    (setq *error* olderr)
  )
  (graphscr)
  (setq oldmode (getvar "osmode"))
  (setq oce (getvar "cmdecho"))
  (setvar "cmdecho" 0)
  (command ".ucs" "W")
  ;;也可以用其他方式取得点集
  (setq	sl '((0 . "POINT")))
  (setq t0 (getvar "TDUSRTIMER"))
  (setq ss (ssget sl))
  (setq ptlist (getpt ss))
  ;;分类
  (setq t0 (getvar "TDUSRTIMER"))
  (setq ptlist (sortx ptlist))
  (princ "\n函数排序用时")
  (princ (* (- (getvar "TDUSRTIMER") t0) 86400))
  (princ "秒")
  ;;函数用时估算,以了解函数性能
  (setq t0 (getvar "TDUSRTIMER"))
  (setq pp1 (f2 ptlist) pp (cadr pp1))
  (princ "\n函数查找用时")
  (princ (* (- (getvar "TDUSRTIMER") t0) 86400))
  (princ "秒")
  (if (= nil pp)
    (progn
      (alert "不存在有最小距离的一对点!")
      (command ".ucs" "p")
      (setvar "osmode" oldmode)
      (setvar "cmdecho" oce)
      (princ)
    )
    (progn
      ;;画最短距离的点对集的连线,可能有多条
      (setvar "osmode" 0)
      (foreach nn pp 
        (entmake
	  (append
	    '((0 . "line")(100 . "AcDbEntity")(100 . "AcDbLine"))
	    (list (cons 10 (car  nn)))
	    (list (cons 11 (cadr nn)))
	    (list (cons 62 1))
	  )
        )
      )
      (command ".ucs" "P")
      (setvar "osmode" oldmode)
      (setvar "cmdecho" oce)
      (princ)
    )
  )
)
;;取点函数,其中i为点的编号
(defun getpt (ss / i listpp a b c) 
  (setq i 0 listpp nil ) 
  (if ss 
    (repeat (sslength ss) 
      (setq a (ssname ss i)) 
      (setq b (entget a)) 
      (setq c (cdr (assoc 10 b)))
      (setq listpp (cons c listpp)) 
      (setq i (1+ i))  
    ) 
  ) 
  (reverse listpp)
)
;;从J到K的表
(defun cut (ptlist j k / i ptlist1)
  (setq i 0 ptlist1 nil)
  (foreach n ptlist
    (if (and (>= i j) (<= i k) )
      (setq ptlist1 (cons n ptlist1))
    )
    (setq i (1+ i))
  )
  (reverse ptlist1)
)
;;对X排序
(defun sortX (ptlist)
  (vl-sort ptlist '(lambda (e1 e2) (< (car e1)(car e2))))
)
;;在带形区域查找
(defun searchX (ptlist1 x1 x2 / pp)
  ;;(vl-remove-if '(lambda (x)(and (>= (car x) x1)(<= (car x) x2))) ptlist1)
  (setq pp nil)
  (foreach n ptlist1
    (if (and (>= (car n) x1)
	     (<= (car n) x2)
	)
      (setq pp (cons n pp))
    )
  )
  (reverse pp)
)
;;在矩形区域查找
(defun searchXY (ptlist2 x1 x2 y1 y2 / pp)
  (setq pp nil)
  (foreach n ptlist2
    (if (and (>= (car  n) x1)
	     (<= (car  n) x2)
	     (>= (cadr n) y1)
	     (<= (cadr n) y2)
	)
      (setq pp (cons n pp))
    )
  )
  (reverse pp)
)
;;最多6点最小距离
(defun 6ptmin (ptlist4 pt / 6pmin 6plist)
  (setq 6pmin (mapcar '(lambda (x) (distance x pt)) ptlist4))
  (setq 6pmin (apply 'min 6pmin) 6plist nil) 
  (foreach 6name ptlist4
    (if (equal (distance 6name pt) 6pmin 1e-6)
      (setq 6plist (cons (list pt 6name) 6plist)) 
    )  
  )
  (list (+ 6pmin 1e-6) 6plist) 		      
)
;;***************
;;程序主段-------
(defun f2 (ptlist / l p1 p2 p3 dd 3pmind 3plist ptlist1 ptlist2 ptlist3 ptlist4  
	         n m midpt mind1 mind2 mindt a b c d Dismin Dnmin nplist mindi)
  (setq l (length ptlist))	
  (cond
    ( (= l 2);;两点还用说    
      (list (+ (distance (car ptlist) (cadr ptlist)) 1e-6)
	    (list ptlist)
      )
    )
    ( (= l 3);;三点最小距离直接求解点对
      (progn
	(setq p1 (car ptlist) p2 (cadr ptlist) p3 (caddr ptlist))
	(setq dd
          (list (list (distance p1 p2) (list p1 p2))
		(list (distance p1 p3) (list p1 p3))
		(list (distance p2 p3) (list p2 p3))
	  )
	)
	(setq 3pmind (apply 'min (mapcar 'car dd)))
	(setq 3plist nil)
	(foreach 3name dd
	  (if (equal (car 3name) 3pmind 1e-6)
	    (setq 3plist (cons (cadr 3name) 3plist))
	  )
	)
        (list (+ 3pmind 1e-6) 3plist)
      )
    )
    ( (> l 2)
      (progn
	(setq n (/ l 2) m (- l n));;分治
	(setq ptlist1 (cut ptlist 0 (1- m)))
	(setq ptlist2 (cut ptlist m l))
	(setq midpt (last ptlist1))
	(setq mind1 (f2 ptlist1));;递归左边
	(setq mind2 (f2 ptlist2));;递归右边
	(setq mindT
	  (cond
	    ((equal (car mind1) (car mind2) 1e-6)(list (car mind1) (append (cadr mind1) (cadr mind2))))
	    ((< (car mind1) (car mind2)) mind1)
	    (t mind2)
	  )
	)
	(setq mindi (car mindT))
	(setq a (- (car midpt) mindi) b (car midpt))
	(setq ptlist3 (searchX ptlist1 a b))
	(if (/= ptlist3 nil)
	  (progn 
	    (setq Dismin nil)
            (foreach name ptlist3
	      (setq a (car midpt) b (+ (car midpt) mindi) c (- (cadr name) mindi) d (+ (cadr name) mindi))
	      (setq ptlist4 (searchXY ptlist2 a b c d))
	      (if (/= ptlist4 nil)
                (setq Dismin (cons (6ptmin ptlist4 name) Dismin))
	      )
	    )
	    (if (= Dismin nil)
	      mindT
	      (progn
	        (setq Dnmin (apply 'min (mapcar 'car Dismin)) nplist nil)
		(foreach npname Dismin
		  (if (equal (car npname) Dnmin 1e-6)
		    (setq nplist (append (cadr npname) nplist))
		  )
		)
	        (cond
		  ((equal (car mindT) Dnmin 1e-6) (list mindi (append nplist (cadr mindT))))
		  ((< (car mindT) Dnmin) mindT)  
	          (t (list Dnmin nplist))
	        );;for inest cond
	      );;for inest if-progn
	    );;for inest if
	  )mindT;;for if-progn
	);;for if
      );;for cond-last-progn
    );;for cond-last
  );;for cond
);;for defun
;;***************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -