One more thing, I've noticed that this line isn't going to do the job
Code:
(not (member avrpt avrlst))
so I've finally revised my last code - little bit slower, but better this :
Code:
(defun averpttriang (triangle)
(mapcar '(lambda (a b c) (/ (+ a b c) 3.0)) (car triangle) (cadr triangle) (caddr triangle))
)
(defun unique (lst)
(if lst (cons (car lst) (unique (vl-remove (car lst) (cdr lst)))))
)
(defun uniquetriangles (triangles / lst assoctriangles uniquetriangs)
(foreach triangle triangles
(setq lst (cons (averpttriang triangle) lst))
)
(setq lst (unique lst))
(foreach triangle triangles
(setq assoctriangles (cons (cons (averpttriang triangle) triangle) assoctriangles))
)
(foreach averpt lst
(setq uniquetriangs (cons (cdr (assoc averpt assoctriangles)) uniquetriangs))
)
uniquetriangs
)
(defun nearest (pt lst / d1 d2 p1 p2)
(setq lst (vl-remove pt lst))
(setq d1 (distance pt (car lst)) p1 (car lst))
(foreach p2 (cdr lst)
(if (> d1 (setq d2 (distance pt p2)))
(setq d1 d2 p1 p2)
)
)
p1
)
(defun mid (p1 p2)
(mapcar '(lambda (a b) (/ (+ a b) 2.0)) p1 p2)
)
(defun circumtriang (p1 p2 p3 / pp1 pp2 pp3 mp1p2 mp2p3 npmp1p2 npmp2p3 cen rad)
(setq pp1 (list (car p1) (cadr p1)))
(setq pp2 (list (car p2) (cadr p2)))
(setq pp3 (list (car p3) (cadr p3)))
(setq mp1p2 (mid pp1 pp2))
(setq mp2p3 (mid pp2 pp3))
(setq npmp1p2 (polar mp1p2 (+ (angle pp1 pp2) (/ pi 2.0)) 1.0))
(setq npmp2p3 (polar mp2p3 (+ (angle pp2 pp3) (/ pi 2.0)) 1.0))
(setq cen (inters mp1p2 npmp1p2 mp2p3 npmp2p3 nil))
(setq rad (distance cen p1))
(list cen rad)
)
(defun ptinsidecir (pt circle)
(setq pt (list (car pt) (cadr pt)))
(> (cadr circle) (distance (car circle) pt))
)
(defun c:triangulate ( / ss n pt ptlst pttlst p1 p2 p3 p2lst p3lst loop2 loop3 k circle pp lst triangles)
(setq ss (ssget '((0 . "POINT"))))
(repeat (setq n (sslength ss))
(setq pt (cdr (assoc 10 (entget (ssname ss (setq n (1- n)))))))
(setq ptlst (cons pt ptlst))
)
(setq pttlst ptlst)
(while (> (length ptlst) 2)
(setq p1 (car ptlst))
(setq p2lst (cdr ptlst))
(setq loop2 T)
(while loop2
(setq p2 (car p2lst))
(setq p2lst (cdr p2lst))
(setq p3lst (vl-remove p2 (cdr ptlst)))
(setq k 0)
(setq loop3 T)
(while loop3
(setq p3 (car p3lst))
(setq p3lst (cdr p3lst))
(setq circle (circumtriang p1 p2 p3))
(setq pp (nearest (car circle) (vl-remove p1 (vl-remove p2 (vl-remove p3 pttlst)))))
(if (not (ptinsidecir pp circle))
(progn
(setq lst (cons p1 lst) lst (cons p2 lst) lst (cons p3 lst))
(setq triangles (cons lst triangles))
(setq k (1+ k))
)
)
(setq lst nil)
(if (equal p1 (car ptlst) 1e-8) (setq ptlst (cdr ptlst)))
(if (or (eq p3lst nil) (eq k 2)) (setq loop3 nil))
(if (or (= (length ptlst) 2) (eq p2lst nil)) (setq loop2 nil))
)
)
)
(foreach triangle (uniquetriangles triangles)
(entmake (list (cons 0 "3DFACE")(cons 10 (car triangle))(cons 11 (cadr triangle))(cons 12 (caddr triangle))(cons 13 (caddr triangle))))
)
(princ)
)
than this slower variant :
Code:
(defun nearest (pt lst / d1 d2 p1 p2)
(setq lst (vl-remove pt lst))
(setq d1 (distance pt (car lst)) p1 (car lst))
(foreach p2 (cdr lst)
(if (> d1 (setq d2 (distance pt p2)))
(setq d1 d2 p1 p2)
)
)
p1
)
(defun averpttriang (p1 p2 p3)
(mapcar '(lambda (a b c) (/ (+ a b c) 3.0)) p1 p2 p3)
)
(defun mid (p1 p2)
(mapcar '(lambda (a b) (/ (+ a b) 2.0)) p1 p2)
)
(defun circumtriang (p1 p2 p3 / pp1 pp2 pp3 mp1p2 mp2p3 npmp1p2 npmp2p3 cen rad)
(setq pp1 (list (car p1) (cadr p1)))
(setq pp2 (list (car p2) (cadr p2)))
(setq pp3 (list (car p3) (cadr p3)))
(setq mp1p2 (mid pp1 pp2))
(setq mp2p3 (mid pp2 pp3))
(setq npmp1p2 (polar mp1p2 (+ (angle pp1 pp2) (/ pi 2.0)) 1.0))
(setq npmp2p3 (polar mp2p3 (+ (angle pp2 pp3) (/ pi 2.0)) 1.0))
(setq cen (inters mp1p2 npmp1p2 mp2p3 npmp2p3 nil))
(setq rad (distance cen p1))
(list cen rad)
)
(defun ptinsidecir (pt circle)
(setq pt (list (car pt) (cadr pt)))
(> (cadr circle) (distance (car circle) pt))
)
(defun c:triangulate ( / ss n pt ptlst pttlst p1 p2 p3 p2lst p3lst loop2 loop3 k circle pp lst avrpt avrlst tst triangles)
(setq ss (ssget '((0 . "POINT"))))
(repeat (setq n (sslength ss))
(setq pt (cdr (assoc 10 (entget (ssname ss (setq n (1- n)))))))
(setq ptlst (cons pt ptlst))
)
(setq pttlst ptlst)
(while (> (length ptlst) 2)
(setq p1 (car ptlst))
(setq p2lst (cdr ptlst))
(setq loop2 T)
(while loop2
(setq p2 (car p2lst))
(setq p2lst (cdr p2lst))
(setq p3lst (vl-remove p2 (cdr ptlst)))
(setq k 0)
(setq loop3 T)
(while loop3
(setq p3 (car p3lst))
(setq p3lst (cdr p3lst))
(setq circle (circumtriang p1 p2 p3))
(setq pp (nearest (car circle) (vl-remove p1 (vl-remove p2 (vl-remove p3 pttlst)))))
(if (not (ptinsidecir pp circle))
(progn
(setq lst (cons p1 lst) lst (cons p2 lst) lst (cons p3 lst))
(setq avrpt (averpttriang p1 p2 p3))
(setq k (1+ k))
)
(setq avrpt nil)
)
(if avrpt
(if avrlst
(foreach pt avrlst
(if (not (equal avrpt pt 1e-6)) (setq tst (cons T tst)) (setq tst (cons nil tst)))
)
(setq tst (cons T tst) tst (cons T tst))
)
)
(if tst
(if (eval (cons 'and tst))
(progn
(setq avrlst (cons avrpt avrlst))
(setq triangles (cons lst triangles))
)
)
)
(setq lst nil)
(setq tst nil)
(if (equal p1 (car ptlst) 1e-8) (setq ptlst (cdr ptlst)))
(if (or (eq p3lst nil) (eq k 2)) (setq loop3 nil))
(if (or (= (length ptlst) 2) (eq p2lst nil)) (setq loop2 nil))
)
)
)
(foreach triangle triangles
(entmake (list (cons 0 "3DFACE")(cons 10 (car triangle))(cons 11 (cadr triangle))(cons 12 (caddr triangle))(cons 13 (caddr triangle))))
)
(princ)
)
Still the best is DTM.vlx if it doesn't break...
My version can't break, but it's so slow, slow, slow... (200 pts approx 15min, and DTM 200 pts approx 5sec)
M.R.
Bookmarks