Author Topic: ==={Challenge}=== Voronoi diagram  (Read 7288 times)

0 Members and 1 Guest are viewing this topic.

ribarm

  • Gator
  • Posts: 3257
  • Marko Ribar, architect
==={Challenge}=== Voronoi diagram
« on: August 08, 2013, 02:27:09 AM »
Hi all...

Recently I've been experimenting with Delunay triangulation and Vonoroi diagram, and I realized I can't make one correctly without help of someone like Evgeniy or Lee... I used Evgeniy's code for triangulation and tried to build Vonoroi diagram based on triangles obtained after trunagulate... But no success, all I get is mess as I don't know how to correctly connect triangles circumcenters...

Here is what I've got so far :
Code: [Select]
(defun c:test (/ i s ext)
  (princ (strcat "\n select points"))
  (if (setq i 0
            s (ssget '((0 . "POINT")))
      )
      (repeat (sslength s)
        (setq pl (cons (cdr (assoc 10 (entget (ssname s i)))) pl)
              i  (1+ i)
        )
      )
  )
  (triangulate pl)
  (setq ext (ACET-GEOM-SS-EXTENTS-ACCURATE (ssget "_X" '((0 . "3DFACE") (8 . "TIN")))))
  (setq pl (vl-sort pl '(lambda (a b) (< (distance a (car ext)) (distance b (car ext))))))

  (or (tblsearch "LAYER" "Vonoroi")
      (entmake (list
                 '(0 . "LAYER")
                 '(100 . "AcDbSymbolTableRecord")
                 '(100 . "AcDbLayerTableRecord")
                 '(2 . "Vonoroi")     '(70 . 0)
                 '(62 . 1)            '(6 . "Continuous")
                 '(290 . 1)           '(370 . -3)
                )
      )
  )

  (start (list (car pl) (cadr pl)))
)

(defun start (lst / ss pll)
  (command "_.region" (ssget "_F" lst '((0 . "3DFACE") (8 . "TIN"))) "")
  (command "_.union" (ssget "_X" '((0 . "REGION") (8 . "TIN"))) "")
  (command "_.explode" (entlast) "")
  (setq ss (ssget "_X" '((0 . "LINE") (8 . "TIN"))))
  (command "pedit" "_m" ss "" "_y" "_j" "" "")
  (setq pll (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget (entlast)))))
  (entdel (entlast))
  (vonoroi pll lst)
  (princ)
)

(defun vonoroi (lst lstt / ss i tr p1 p2 p3 p12 p23 p31 llst o ol oll)
  (command "_.erase" (ssget "_X" '((0 . "3DFACE") (8 . "TIN"))) "")
  (triangulate pl)
  (setq ss (ssget "_F" lst '((0 . "3DFACE") (8 . "TIN"))))
  (setq i -1)
  (while (setq tr (ssname ss (setq i (1+ i))))
    (setq p1 (cdr (assoc 11 (entget tr)))
          p2 (cdr (assoc 12 (entget tr)))
          p3 (cdr (assoc 13 (entget tr)))
    )
    (setq p12 (mid p1 p2)
          p23 (mid p2 p3)
          p31 (mid p3 p1)
    )
    (if (member-fuzz p1 lstt 1e-6) (setq llst (vl-remove p1 lst)))
    (if (member-fuzz p2 lstt 1e-6) (setq llst (vl-remove p2 lst)))
    (if (member-fuzz p3 lstt 1e-6) (setq llst (vl-remove p3 lst)))
    (setq o (inters p12 (mapcar '+ p12 (polar '(0.0 0.0 0.0) (+ (angle p1 p2) (* pi 0.5)) 1.0)) p23 (mapcar '+ p23 (polar '(0.0 0.0 0.0) (+ (angle p2 p3) (* pi 0.5)) 1.0)) nil))
    (setq ol (cons o ol))
  )
  (setq oll (cons ol oll))
  (if llst
    (start llst)
    (mapcar '(lambda (a b) (entmake (list '(0 . "LINE") '(8 . "Vonoroi") (cons 10 a) (cons 11 b)))) (apply 'append (reverse oll)) (cdr (apply 'append (reverse oll))))
    ;;; (mapcar '(lambda (a b) (entmake (list '(0 . "LINE") '(8 . "Vonoroi") (cons 10 a) (cons 11 b)))) (apply 'append (apply 'mapcar (cons 'list (reverse oll)))) (cdr (apply 'append (apply 'mapcar (cons 'list (reverse oll)))))) - If I transpose list with lists of points, I also get bad results ;;;
  )
)

(defun member-fuzz (el lst fuzz)
  (vl-member-if '(lambda (x) (equal x el fuzz)) lst)
)

(defun mid (p1 p2)
  (mapcar '(lambda (a b) (/ (+ a b) 2.0)) p1 p2)
)

(defun triangulate (pl / a b c i i1 i2 bb sl al el tl l ma mi tr x1 x2
                    y1 y2 p r cp)

  (if pl
    (progn
      (setq
        i  1
        i1 (/ (length pl) 100.)
        i2 0
        pl (vl-sort pl
                    (function (lambda (a b) (< (car a) (car b))))
           )
        bb (list (apply 'mapcar (cons 'min pl))
                 (apply 'mapcar (cons 'max pl))
           )

        x1 (caar bb)
        x2 (caadr bb)
        y1 (cadar bb)
        y2 (cadadr bb)


      )
      (setq cp (list (/ (+ x1 x2) 2.0) (/ (+ y1 y2) 2.0))
            r  (* (distance cp (list x1 y1)) 20)
            ma (+ (car cp) r)
            mi (- (car cp) r)
            sl (list (list ma (cadr cp) 0)
                     (list mi (+ (cadr cp) r) 0)
                     (list mi (- (cadr cp) r) 0)
               )

            al (list (cons x2 (cons cp (cons (* 20 r) sl))))

            ma (1- ma)
            mi (1+ mi)
      )

      (repeat (length pl)

        (setq p  (car pl)
              pl (cdr pl)
              el nil
        )
        (while al
          (setq tr (car al)
                al (cdr al)
          )
          (cond
            ((< (car tr) (car p)) (setq tl (cons (cdddr tr) tl)))
            ((< (distance p (cadr tr)) (caddr tr))
             (setq tr (cdddr tr)
                   a  (car tr)
                   b  (cadr tr)
                   c  (caddr tr)
                   el (cons (list (+ (car a) (car b))
                                  (+ (cadr a) (cadr b))
                                  a
                                  b
                            )
                            (cons (list (+ (car b) (car c))
                                        (+ (cadr b) (cadr c))
                                        b
                                        c
                                  )
                                  (cons (list (+ (car c) (car a))
                                              (+ (cadr c) (cadr a))
                                              c
                                              a
                                        )
                                        el
                                  )
                            )
                      )

             )
            )
            (t (setq l (cons tr l)))
          )
        )

        (setq al l
              l  nil

              el (vl-sort el
                          (function (lambda (a b)
                                      (if (= (car a) (car b))
                                        (<= (cadr a) (cadr b))
                                        (< (car a) (car b))
                                      )
                                    )
                          )
                 )
        )

        (while el
          (if (and (= (caar el) (caadr el))
                   (= (cadar el) (cadadr el))
              )
            (setq el (cddr el))
            (setq al (cons (getcircumcircle p (cddar el)) al)
                  el (cdr el)
            )
          )
        )
      )

      (foreach tr al (setq tl (cons (cdddr tr) tl)))

      (setq
        tl (vl-remove-if-not
             (function
               (lambda (a)
                 (and (< mi (caadr a) ma) (< mi (caaddr a) ma))
               )
             )
             tl
           )
      )

      (or (tblsearch "LAYER" "TIN")
          (entmake (list
                     '(0 . "LAYER")
                     '(100 . "AcDbSymbolTableRecord")
                     '(100 . "AcDbLayerTableRecord")
                     '(2 . "TIN")         '(70 . 0)
                     '(62 . 8)            '(6 . "Continuous")
                     '(290 . 1)           '(370 . -3)
                    )
          )
      )

      (setvar "CLAYER" "TIN")

      (foreach tr tl
        (entmake (list (cons 0 "3DFACE")
                       (cons 10 (car tr))
                       (cons 11 (car tr))
                       (cons 12 (cadr tr))
                       (cons 13 (caddr tr))
                 )
        )
      )
    )
  )
  (princ)
)

(defun getcircumcircle (a el / b c c2 cp r ang)
  (setq b  (car el)
        c  (cadr el)
        c2 (list (car c) (cadr c))
  )
  (if (not
        (zerop
          (setq ang (- (angle b c) (angle b a)))
        )
      )
    (progn (setq cp (polar c2
                           (+ -1.570796326794896 (angle c a) ang)
                           (setq r (/ (distance a c2) (sin ang) 2.0))
                    )
                 r  (abs r)
           )
           (list (+ (car cp) r) cp r a b c)
    )
  )
)

Thanks, M.R.
« Last Edit: August 11, 2013, 06:23:53 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3257
  • Marko Ribar, architect
Re: ==={Challenge}=== Vonoroi diagram
« Reply #1 on: August 08, 2013, 05:21:34 AM »
This won't work also...

Code: [Select]
(defun c:test (/ i s)
  (princ (strcat "\n select points"))
  (if (setq i 0
            s (ssget '((0 . "POINT")))
      )
      (repeat (sslength s)
        (setq pl (cons (cdr (assoc 10 (entget (ssname s i)))) pl)
              i  (1+ i)
        )
      )
  )
  (triangulate pl)
)

(defun triangulate (pl / a b c i i1 i2 bb sl al el tl l ma mi tr x1 x2
                    y1 y2 p r cp)

  (if pl
    (progn
      (setq
        i  1
        i1 (/ (length pl) 100.)
        i2 0
        pl (vl-sort pl
                    (function (lambda (a b) (< (car a) (car b))))
           )
        bb (list (apply 'mapcar (cons 'min pl))
                 (apply 'mapcar (cons 'max pl))
           )

        x1 (caar bb)
        x2 (caadr bb)
        y1 (cadar bb)
        y2 (cadadr bb)


      )
      (setq cp (list (/ (+ x1 x2) 2.0) (/ (+ y1 y2) 2.0))
            r  (* (distance cp (list x1 y1)) 20)
            ma (+ (car cp) r)
            mi (- (car cp) r)
            sl (list (list ma (cadr cp) 0)
                     (list mi (+ (cadr cp) r) 0)
                     (list mi (- (cadr cp) r) 0)
               )

            al (list (cons x2 (cons cp (cons (* 20 r) sl))))

            ma (1- ma)
            mi (1+ mi)
      )

      (repeat (length pl)

        (setq p  (car pl)
              pl (cdr pl)
              el nil
        )
        (while al
          (setq tr (car al)
                al (cdr al)
          )
          (cond
            ((< (car tr) (car p)) (setq tl (cons (cdddr tr) tl)))
            ((< (distance p (cadr tr)) (caddr tr))
             (setq tr (cdddr tr)
                   a  (car tr)
                   b  (cadr tr)
                   c  (caddr tr)
                   el (cons (list (+ (car a) (car b))
                                  (+ (cadr a) (cadr b))
                                  a
                                  b
                            )
                            (cons (list (+ (car b) (car c))
                                        (+ (cadr b) (cadr c))
                                        b
                                        c
                                  )
                                  (cons (list (+ (car c) (car a))
                                              (+ (cadr c) (cadr a))
                                              c
                                              a
                                        )
                                        el
                                  )
                            )
                      )

             )
            )
            (t (setq l (cons tr l)))
          )
        )

        (setq al l
              l  nil

              el (vl-sort el
                          (function (lambda (a b)
                                      (if (= (car a) (car b))
                                        (<= (cadr a) (cadr b))
                                        (< (car a) (car b))
                                      )
                                    )
                          )
                 )
        )

        (while el
          (if (and (= (caar el) (caadr el))
                   (= (cadar el) (cadadr el))
              )
            (setq el (cddr el))
            (setq al (cons (getcircumcircle p (cddar el)) al)
                  el (cdr el)
            )
          )
        )
      )

      (foreach tr al (setq tl (cons (cdddr tr) tl)))

      (setq
        tl (vl-remove-if-not
             (function
               (lambda (a)
                 (and (< mi (caadr a) ma) (< mi (caaddr a) ma))
               )
             )
             tl
           )
      )

      (or (tblsearch "LAYER" "TIN")
          (entmake (list
                     '(0 . "LAYER")
                     '(100 . "AcDbSymbolTableRecord")
                     '(100 . "AcDbLayerTableRecord")
                     '(2 . "TIN")         '(70 . 0)
                     '(62 . 8)            '(6 . "Continuous")
                     '(290 . 1)           '(370 . -3)
                    )
          )
      )

      (or (tblsearch "LAYER" "Vonoroi")
          (entmake (list
                     '(0 . "LAYER")
                     '(100 . "AcDbSymbolTableRecord")
                     '(100 . "AcDbLayerTableRecord")
                     '(2 . "Vonoroi")     '(70 . 0)
                     '(62 . 1)            '(6 . "Continuous")
                     '(290 . 1)           '(370 . -3)
                    )
          )
      )

      (setvar "CLAYER" "TIN")

      (foreach tr tl
        (entmake (list (cons 0 "3DFACE")
                       (cons 10 (car tr))
                       (cons 11 (car tr))
                       (cons 12 (cadr tr))
                       (cons 13 (caddr tr))
                 )
        )
      )

      (mapcar '(lambda (tr1 tr2) (entmake (list '(0 . "LINE") '(8 . "Vonoroi") (cons 10 (otr tr1)) (cons 11 (otr tr2))))) tl (cdr tl))
    )
  )
  (princ)
)

(defun mid (p1 p2)
  (mapcar '(lambda (a b) (/ (+ a b) 2.0)) p1 p2)
)

(defun otr (tr / p1 p2 p3 p12 p23 p31 o)
  (setq p1 (car tr)
        p2 (cadr tr)
        p3 (caddr tr)
  )
  (setq p12 (mid p1 p2)
        p23 (mid p2 p3)
        p31 (mid p3 p1)
  )
  (setq o (inters p12 (mapcar '+ p12 (polar '(0.0 0.0 0.0) (+ (angle p1 p2) (* pi 0.5)) 1.0)) p23 (mapcar '+ p23 (polar '(0.0 0.0 0.0) (+ (angle p2 p3) (* pi 0.5)) 1.0)) nil))
  o
)

(defun getcircumcircle (a el / b c c2 cp r ang)
  (setq b  (car el)
        c  (cadr el)
        c2 (list (car c) (cadr c))
  )
  (if (not
        (zerop
          (setq ang (- (angle b c) (angle b a)))
        )
      )
    (progn (setq cp (polar c2
                           (+ -1.570796326794896 (angle c a) ang)
                           (setq r (/ (distance a c2) (sin ang) 2.0))
                    )
                 r  (abs r)
           )
           (list (+ (car cp) r) cp r a b c)
    )
  )
)

Anyone, help, thanks...
 :-(
« Last Edit: August 08, 2013, 06:03:01 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3257
  • Marko Ribar, architect
Re: ==={Challenge}=== Vonoroi diagram
« Reply #2 on: August 08, 2013, 06:00:46 AM »
Neither this, my old slow algorithm for up to 100 pts won't work...

Code: [Select]
(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 flatten (lst / lstn)
  (foreach triangle (reverse lst)
    (setq lstn (cons (caddr triangle) lstn) lstn (cons (cadr triangle) lstn) lstn (cons (car triangle) lstn))
  )
  (reverse lstn)
)

(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 otr (tr / p1 p2 p3 p12 p23 p31 o)
  (setq p1 (car tr)
        p2 (cadr tr)
        p3 (caddr tr)
  )
  (setq p12 (mid p1 p2)
        p23 (mid p2 p3)
        p31 (mid p3 p1)
  )
  (setq o (inters p12 (mapcar '+ p12 (polar '(0.0 0.0 0.0) (+ (angle p1 p2) (* pi 0.5)) 1.0)) p23 (mapcar '+ p23 (polar '(0.0 0.0 0.0) (+ (angle p2 p3) (* pi 0.5)) 1.0)) nil))
  o
)

(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 p2lstt p2lst p3lst loop2 loop3 k circle pp lst triangles tl)
  (setq ss (ssget '((0 . "POINT"))))
  (vl-cmdf "_.time" "r" "")
  (repeat (setq n (sslength ss))
    (setq pt (cdr (assoc 10 (entget (ssname ss (setq n (1- n)))))))
    (setq ptlst (cons pt ptlst))
  )
  (setq ptlst (vl-sort ptlst '(lambda (a b) (< (car a) (car b)))))
  (setq pttlst ptlst)
  (acet-ui-progress "Progress : " n)
  (while (> (length ptlst) 2)
    (setq p1 (car ptlst))
    (setq p2lst (cdr ptlst))
    (setq p2lstt p2lst)
    (setq loop2 T)
    (while loop2
      (setq p2 (car p2lst))
      (setq p2lst (cdr p2lst))
      (setq p3lst (vl-remove p2 p2lstt))
      (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 (eq k 2) (setq loop3 nil p2lst (vl-remove p3 p2lst) p2lst (cons p3 p2lst)))
        (if (and (eq k 2) (member p3 (flatten (cdr triangles)))) (setq loop2 nil))
        (if (eq p3lst nil) (setq loop3 nil))
        (if (or (= (length ptlst) 2) (eq p2lst nil)) (setq loop2 nil))
      )
    )
    (acet-ui-progress -1)
  )
  (or (tblsearch "LAYER" "TIN")
      (entmake (list
                 '(0 . "LAYER")
                 '(100 . "AcDbSymbolTableRecord")
                 '(100 . "AcDbLayerTableRecord")
                 '(2 . "TIN")         '(70 . 0)
                 '(62 . 8)            '(6 . "Continuous")
                 '(290 . 1)           '(370 . -3)
                )
      )
  )
  (or (tblsearch "LAYER" "Vonoroi")
      (entmake (list
                 '(0 . "LAYER")
                 '(100 . "AcDbSymbolTableRecord")
                 '(100 . "AcDbLayerTableRecord")
                 '(2 . "Vonoroi")     '(70 . 0)
                 '(62 . 1)            '(6 . "Continuous")
                 '(290 . 1)           '(370 . -3)
                )
      )
  )
  (setvar "CLAYER" "TIN")
  (foreach triangle (setq tl (uniquetriangles triangles))
    (entmake (list (cons 0 "3DFACE")(cons 10 (car triangle))(cons 11 (cadr triangle))(cons 12 (caddr triangle))(cons 13 (caddr triangle))))
  )
  (mapcar '(lambda (tr1 tr2) (entmake (list '(0 . "LINE") '(8 . "Vonoroi") (cons 10 (otr tr1)) (cons 11 (otr tr2))))) tl (cdr tl))
  (acet-ui-progress-done)
  (vl-cmdf "_.time" "d" "")
  (princ)
)

M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3257
  • Marko Ribar, architect
Re: ==={Challenge}=== Vonoroi diagram
« Reply #3 on: August 08, 2013, 09:28:45 AM »
This is better, but not just what should it be...

Please study this link :
http://www.cs.cornell.edu/home/chew/Delaunay.html

Code: [Select]
(defun c:test (/ i s)
  (princ (strcat "\n select points"))
  (if (setq i 0
            s (ssget '((0 . "POINT")))
      )
      (repeat (sslength s)
        (setq pl (cons (cdr (assoc 10 (entget (ssname s i)))) pl)
              i  (1+ i)
        )
      )
  )
  (triangulate pl)
)

(defun triangulate (pl / a b c i i1 i2 bb sl al el tl l ma mi tr x1 x2
                    y1 y2 p r cp ol oll)

  (if pl
    (progn
      (setq
        i  1
        i1 (/ (length pl) 100.)
        i2 0
        pl (vl-sort pl
                    (function (lambda (a b) (< (car a) (car b))))
           )
        bb (list (apply 'mapcar (cons 'min pl))
                 (apply 'mapcar (cons 'max pl))
           )

        x1 (caar bb)
        x2 (caadr bb)
        y1 (cadar bb)
        y2 (cadadr bb)


      )
      (setq cp (list (/ (+ x1 x2) 2.0) (/ (+ y1 y2) 2.0))
            r  (* (distance cp (list x1 y1)) 20)
            ma (+ (car cp) r)
            mi (- (car cp) r)
            sl (list (list ma (cadr cp) 0)
                     (list mi (+ (cadr cp) r) 0)
                     (list mi (- (cadr cp) r) 0)
               )

            al (list (cons x2 (cons cp (cons (* 20 r) sl))))

            ma (1- ma)
            mi (1+ mi)
      )

      (repeat (length pl)

        (setq p  (car pl)
              pl (cdr pl)
              el nil
        )
        (while al
          (setq tr (car al)
                al (cdr al)
          )
          (cond
            ((< (car tr) (car p)) (setq tl (cons (cdddr tr) tl)))
            ((< (distance p (cadr tr)) (caddr tr))
             (setq tr (cdddr tr)
                   a  (car tr)
                   b  (cadr tr)
                   c  (caddr tr)
                   el (cons (list (+ (car a) (car b))
                                  (+ (cadr a) (cadr b))
                                  a
                                  b
                            )
                            (cons (list (+ (car b) (car c))
                                        (+ (cadr b) (cadr c))
                                        b
                                        c
                                  )
                                  (cons (list (+ (car c) (car a))
                                              (+ (cadr c) (cadr a))
                                              c
                                              a
                                        )
                                        el
                                  )
                            )
                      )

             )
            )
            (t (setq l (cons tr l)))
          )
        )

        (setq al l
              l  nil

              el (vl-sort el
                          (function (lambda (a b)
                                      (if (= (car a) (car b))
                                        (<= (cadr a) (cadr b))
                                        (< (car a) (car b))
                                      )
                                    )
                          )
                 )
        )

        (while el
          (if (and (= (caar el) (caadr el))
                   (= (cadar el) (cadadr el))
              )
            (setq el (cddr el))
            (setq al (cons (getcircumcircle p (cddar el)) al)
                  el (cdr el)
            )
          )
        )
      )

      (foreach tr al (setq tl (cons (cdddr tr) tl)))

      (setq
        tl (vl-remove-if-not
             (function
               (lambda (a)
                 (and (< mi (caadr a) ma) (< mi (caaddr a) ma))
               )
             )
             tl
           )
      )

      (or (tblsearch "LAYER" "TIN")
          (entmake (list
                     '(0 . "LAYER")
                     '(100 . "AcDbSymbolTableRecord")
                     '(100 . "AcDbLayerTableRecord")
                     '(2 . "TIN")         '(70 . 0)
                     '(62 . 8)            '(6 . "Continuous")
                     '(290 . 1)           '(370 . -3)
                    )
          )
      )

      (or (tblsearch "LAYER" "Vonoroi")
          (entmake (list
                     '(0 . "LAYER")
                     '(100 . "AcDbSymbolTableRecord")
                     '(100 . "AcDbLayerTableRecord")
                     '(2 . "Vonoroi")     '(70 . 0)
                     '(62 . 1)            '(6 . "Continuous")
                     '(290 . 1)           '(370 . -3)
                    )
          )
      )

      (setvar "CLAYER" "TIN")

      (foreach tr tl
        (entmake (list (cons 0 "3DFACE")
                       (cons 10 (car tr))
                       (cons 11 (car tr))
                       (cons 12 (cadr tr))
                       (cons 13 (caddr tr))
                 )
        )
        (setq ol (cons (otr tr) ol))
      )

      (setq ol (_sortol (car ol) ol))
      (mapcar '(lambda (a b) (entmake (list '(0 . "LINE") '(8 . "Vonoroi") (cons 10 a) (cons 11 b)))) ol (cdr ol))

    )
  )
  (princ)
)

(defun _sortol (pt lst)
  (setq oll (cons (setq pt (NearestFromPoint lst pt)) oll))
  (if (setq lst (vl-remove pt lst)) (_sortol pt lst) (reverse oll))
)

(defun NearestFromPoint (lst pt / 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 otr (tr / p1 p2 p3 p12 p23 p31 o)
  (setq p1 (car tr)
        p2 (cadr tr)
        p3 (caddr tr)
  )
  (setq p12 (mid p1 p2)
        p23 (mid p2 p3)
        p31 (mid p3 p1)
  )
  (setq o (inters p12 (mapcar '+ p12 (polar '(0.0 0.0 0.0) (+ (angle p1 p2) (* pi 0.5)) 1.0)) p23 (mapcar '+ p23 (polar '(0.0 0.0 0.0) (+ (angle p2 p3) (* pi 0.5)) 1.0)) nil))
  o
)

(defun getcircumcircle (a el / b c c2 cp r ang)
  (setq b  (car el)
        c  (cadr el)
        c2 (list (car c) (cadr c))
  )
  (if (not
        (zerop
          (setq ang (- (angle b c) (angle b a)))
        )
      )
    (progn (setq cp (polar c2
                           (+ -1.570796326794896 (angle c a) ang)
                           (setq r (/ (distance a c2) (sin ang) 2.0))
                    )
                 r  (abs r)
           )
           (list (+ (car cp) r) cp r a b c)
    )
  )
)
« Last Edit: August 09, 2013, 12:27:05 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3257
  • Marko Ribar, architect
Re: ==={Challenge}=== Vonoroi diagram
« Reply #4 on: August 08, 2013, 10:38:48 AM »
This code is too slow - it takes ab 10 min. for 500 pts and it produces too many lines...

Code: [Select]
(defun c:test (/ i s)
  (princ (strcat "\n select points"))
  (if (setq i 0
            s (ssget '((0 . "POINT")))
      )
      (repeat (sslength s)
        (setq pl (cons (cdr (assoc 10 (entget (ssname s i)))) pl)
              i  (1+ i)
        )
      )
  )
  (triangulate pl)
)

(defun triangulate (pl / a b c i i1 i2 bb sl al el tl l ma mi tr x1 x2
                    y1 y2 p r cp ol ss)

  (if pl
    (progn
      (setq
        i  1
        i1 (/ (length pl) 100.)
        i2 0
        pl (vl-sort pl
                    (function (lambda (a b) (< (car a) (car b))))
           )
        bb (list (apply 'mapcar (cons 'min pl))
                 (apply 'mapcar (cons 'max pl))
           )

        x1 (caar bb)
        x2 (caadr bb)
        y1 (cadar bb)
        y2 (cadadr bb)


      )
      (setq cp (list (/ (+ x1 x2) 2.0) (/ (+ y1 y2) 2.0))
            r  (* (distance cp (list x1 y1)) 20)
            ma (+ (car cp) r)
            mi (- (car cp) r)
            sl (list (list ma (cadr cp) 0)
                     (list mi (+ (cadr cp) r) 0)
                     (list mi (- (cadr cp) r) 0)
               )

            al (list (cons x2 (cons cp (cons (* 20 r) sl))))

            ma (1- ma)
            mi (1+ mi)
      )

      (repeat (length pl)

        (setq p  (car pl)
              pl (cdr pl)
              el nil
        )
        (while al
          (setq tr (car al)
                al (cdr al)
          )
          (cond
            ((< (car tr) (car p)) (setq tl (cons (cdddr tr) tl)))
            ((< (distance p (cadr tr)) (caddr tr))
             (setq tr (cdddr tr)
                   a  (car tr)
                   b  (cadr tr)
                   c  (caddr tr)
                   el (cons (list (+ (car a) (car b))
                                  (+ (cadr a) (cadr b))
                                  a
                                  b
                            )
                            (cons (list (+ (car b) (car c))
                                        (+ (cadr b) (cadr c))
                                        b
                                        c
                                  )
                                  (cons (list (+ (car c) (car a))
                                              (+ (cadr c) (cadr a))
                                              c
                                              a
                                        )
                                        el
                                  )
                            )
                      )

             )
            )
            (t (setq l (cons tr l)))
          )
        )

        (setq al l
              l  nil

              el (vl-sort el
                          (function (lambda (a b)
                                      (if (= (car a) (car b))
                                        (<= (cadr a) (cadr b))
                                        (< (car a) (car b))
                                      )
                                    )
                          )
                 )
        )

        (while el
          (if (and (= (caar el) (caadr el))
                   (= (cadar el) (cadadr el))
              )
            (setq el (cddr el))
            (setq al (cons (getcircumcircle p (cddar el)) al)
                  el (cdr el)
            )
          )
        )
      )

      (foreach tr al (setq tl (cons (cdddr tr) tl)))

      (setq
        tl (vl-remove-if-not
             (function
               (lambda (a)
                 (and (< mi (caadr a) ma) (< mi (caaddr a) ma))
               )
             )
             tl
           )
      )

      (or (tblsearch "LAYER" "TIN")
          (entmake (list
                     '(0 . "LAYER")
                     '(100 . "AcDbSymbolTableRecord")
                     '(100 . "AcDbLayerTableRecord")
                     '(2 . "TIN")         '(70 . 0)
                     '(62 . 8)            '(6 . "Continuous")
                     '(290 . 1)           '(370 . -3)
                    )
          )
      )

      (or (tblsearch "LAYER" "Vonoroi")
          (entmake (list
                     '(0 . "LAYER")
                     '(100 . "AcDbSymbolTableRecord")
                     '(100 . "AcDbLayerTableRecord")
                     '(2 . "Vonoroi")     '(70 . 0)
                     '(62 . 1)            '(6 . "Continuous")
                     '(290 . 1)           '(370 . -3)
                    )
          )
      )

      (setvar "CLAYER" "TIN")

      (foreach tr tl
        (entmake (list (cons 0 "3DFACE")
                       (cons 10 (car tr))
                       (cons 11 (car tr))
                       (cons 12 (cadr tr))
                       (cons 13 (caddr tr))
                 )
        )
        (setq ol (cons (otr tr) ol))
      )

      (foreach o ol
        (setq ol (_sortol o ol))
        (mapcar '(lambda (a b) (entmake (list '(0 . "LINE") '(8 . "Vonoroi") (cons 10 a) (cons 11 b)))) ol (cdr ol))
        (setq oll nil)
      )
     
      (setq ss (ssget "_X" '((0 . "LINE") (8 . "Vonoroi"))))
      (command "_.-overkill" ss "" "")
     
    )
  )
  (princ)
)

(defun _sortol (pt lst)
  (setq oll (cons (setq pt (NearestFromPoint lst pt)) oll))
  (if (setq lst (vl-remove pt lst)) (_sortol pt lst) (reverse oll))
)

(defun NearestFromPoint (lst pt / 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 otr (tr / p1 p2 p3 p12 p23 p31 o)
  (setq p1 (car tr)
        p2 (cadr tr)
        p3 (caddr tr)
  )
  (setq p12 (mid p1 p2)
        p23 (mid p2 p3)
        p31 (mid p3 p1)
  )
  (setq o (inters p12 (mapcar '+ p12 (polar '(0.0 0.0 0.0) (+ (angle p1 p2) (* pi 0.5)) 1.0)) p23 (mapcar '+ p23 (polar '(0.0 0.0 0.0) (+ (angle p2 p3) (* pi 0.5)) 1.0)) nil))
  o
)

(defun getcircumcircle (a el / b c c2 cp r ang)
  (setq b  (car el)
        c  (cadr el)
        c2 (list (car c) (cadr c))
  )
  (if (not
        (zerop
          (setq ang (- (angle b c) (angle b a)))
        )
      )
    (progn (setq cp (polar c2
                           (+ -1.570796326794896 (angle c a) ang)
                           (setq r (/ (distance a c2) (sin ang) 2.0))
                    )
                 r  (abs r)
           )
           (list (+ (car cp) r) cp r a b c)
    )
  )
)

No avail, I give up... Still any post is welcome...
Thanks, M.R.
« Last Edit: August 09, 2013, 12:26:45 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3257
  • Marko Ribar, architect
Re: ==={Challenge}=== Vonoroi diagram
« Reply #5 on: August 08, 2013, 04:12:08 PM »
Also, too slow code, but till now it gave me better results - some of lines are reduced...

In some cases, you just can't get correct result, but for this 10 pts - see attachment it was OK...
(Do not test it with more than 100 pts)

Code - Auto/Visual Lisp: [Select]
  1. (defun c:test (/ i s)
  2.   (princ (strcat "\n select points"))
  3.   (if (setq i 0
  4.             s (ssget '((0 . "POINT")))
  5.       )
  6.       (repeat (sslength s)
  7.         (setq pl (cons (cdr (assoc 10 (entget (ssname s i)))) pl)
  8.               i  (1+ i)
  9.         )
  10.       )
  11.   )
  12.   (triangulate pl)
  13. )
  14.  
  15. (defun triangulate (pl / a b c i i1 i2 bb sl al el tl l ma mi tr x1 x2
  16.                     y1 y2 p r cp ol rl orl ss li oo o1 o2 r1 r2 in pll)
  17.  
  18.   (if pl
  19.     (progn
  20.       (setq
  21.         pll pl
  22.         i  1
  23.         i1 (/ (length pl) 100.)
  24.         i2 0
  25.         pl (vl-sort pl
  26.                     (function (lambda (a b) (< (car a) (car b))))
  27.            )
  28.         bb (list (apply 'mapcar (cons 'min pl))
  29.                  (apply 'mapcar (cons 'max pl))
  30.            )
  31.  
  32.         x1 (caar bb)
  33.         x2 (caadr bb)
  34.         y1 (cadar bb)
  35.         y2 (cadadr bb)
  36.  
  37.  
  38.       )
  39.       (setq cp (list (/ (+ x1 x2) 2.0) (/ (+ y1 y2) 2.0))
  40.             r  (* (distance cp (list x1 y1)) 20)
  41.             ma (+ (car cp) r)
  42.             mi (- (car cp) r)
  43.             sl (list (list ma (cadr cp) 0)
  44.                      (list mi (+ (cadr cp) r) 0)
  45.                      (list mi (- (cadr cp) r) 0)
  46.                )
  47.  
  48.             al (list (cons x2 (cons cp (cons (* 20 r) sl))))
  49.  
  50.             ma (1- ma)
  51.             mi (1+ mi)
  52.       )
  53.  
  54.       (repeat (length pl)
  55.  
  56.         (setq p  (car pl)
  57.               pl (cdr pl)
  58.               el nil
  59.         )
  60.         (while al
  61.           (setq tr (car al)
  62.                 al (cdr al)
  63.           )
  64.           (cond
  65.             ((< (car tr) (car p)) (setq tl (cons (cdddr tr) tl)))
  66.             ((< (distance p (cadr tr)) (caddr tr))
  67.              (setq tr (cdddr tr)
  68.                    a  (car tr)
  69.                    b  (cadr tr)
  70.                    c  (caddr tr)
  71.                    el (cons (list (+ (car a) (car b))
  72.                                   (+ (cadr a) (cadr b))
  73.                                   a
  74.                                   b
  75.                             )
  76.                             (cons (list (+ (car b) (car c))
  77.                                         (+ (cadr b) (cadr c))
  78.                                         b
  79.                                         c
  80.                                   )
  81.                                   (cons (list (+ (car c) (car a))
  82.                                               (+ (cadr c) (cadr a))
  83.                                               c
  84.                                               a
  85.                                         )
  86.                                         el
  87.                                   )
  88.                             )
  89.                       )
  90.  
  91.              )
  92.             )
  93.             (t (setq l (cons tr l)))
  94.           )
  95.         )
  96.  
  97.         (setq al l
  98.               l  nil
  99.  
  100.               el (vl-sort el
  101.                           (function (lambda (a b)
  102.                                       (if (= (car a) (car b))
  103.                                         (<= (cadr a) (cadr b))
  104.                                         (< (car a) (car b))
  105.                                       )
  106.                                     )
  107.                           )
  108.                  )
  109.         )
  110.  
  111.         (while el
  112.           (if (and (= (caar el) (caadr el))
  113.                    (= (cadar el) (cadadr el))
  114.               )
  115.             (setq el (cddr el))
  116.             (setq al (cons (getcircumcircle p (cddar el)) al)
  117.                   el (cdr el)
  118.             )
  119.           )
  120.         )
  121.       )
  122.  
  123.       (foreach tr al (setq tl (cons (cdddr tr) tl)))
  124.  
  125.       (setq
  126.         tl (vl-remove-if-not
  127.              (function
  128.                (lambda (a)
  129.                  (and (< mi (caadr a) ma) (< mi (caaddr a) ma))
  130.                )
  131.              )
  132.              tl
  133.            )
  134.       )
  135.  
  136.       (or (tblsearch "LAYER" "TIN")
  137.           (entmake (list
  138.                      '(0 . "LAYER")
  139.                      '(100 . "AcDbSymbolTableRecord")
  140.                      '(100 . "AcDbLayerTableRecord")
  141.                      '(2 . "TIN")         '(70 . 0)
  142.                      '(62 . 8)            '(6 . "Continuous")
  143.                      '(290 . 1)           '(370 . -3)
  144.                     )
  145.           )
  146.       )
  147.  
  148.       (or (tblsearch "LAYER" "Vonoroi")
  149.           (entmake (list
  150.                      '(0 . "LAYER")
  151.                      '(100 . "AcDbSymbolTableRecord")
  152.                      '(100 . "AcDbLayerTableRecord")
  153.                      '(2 . "Vonoroi")     '(70 . 0)
  154.                      '(62 . 1)            '(6 . "Continuous")
  155.                      '(290 . 1)           '(370 . -3)
  156.                     )
  157.           )
  158.       )
  159.  
  160.       (setvar "CLAYER" "TIN")
  161.  
  162.       (foreach tr tl
  163.         (entmake (list (cons 0 "3DFACE")
  164.                        (cons 10 (car tr))
  165.                        (cons 11 (car tr))
  166.                        (cons 12 (cadr tr))
  167.                        (cons 13 (caddr tr))
  168.                  )
  169.         )
  170.         (setq ol (cons (setq oo (otr tr)) ol))
  171.         (setq rl (cons (distance oo (car tr)) rl))
  172.       )
  173.  
  174.       (setq orl (mapcar '(lambda (a b) (cons a b)) ol rl))
  175.  
  176.       (foreach o ol
  177.         (setq ol (_sortol o ol))
  178.         (mapcar '(lambda (a b) (entmake (list '(0 . "LINE") '(8 . "Vonoroi") (cons 10 a) (cons 11 b)))) ol (cdr ol))
  179.         (setq oll nil)
  180.       )
  181.      
  182.       (setq ss (ssget "_X" '((0 . "LINE") (8 . "Vonoroi"))))
  183.       (command "_.-overkill" ss "" "")
  184.       (setq ss (ssget "_X" '((0 . "LINE") (8 . "Vonoroi"))))
  185.       (setq i -1)
  186.       (while (setq li (ssname ss (setq i (1+ i))))
  187.         (setq o1 (cdr (assoc 10 (entget li)))
  188.               o2 (cdr (assoc 11 (entget li)))
  189.         )
  190.         (setq r1 (cdr (assocon o1 orl 'car 1e-6))
  191.               r2 (cdr (assocon o2 orl 'car 1e-6))
  192.         )
  193.         (setq in (LM:Inters2Circle o1 r1 o2 r2))
  194.         (if (not (and in (member-fuzz (car in) pll 1e-6) (member-fuzz (cadr in) pll 1e-6))) (entdel li))
  195.       )
  196.      
  197.     )
  198.   )
  199.   (princ)
  200. )
  201.  
  202.  
  203. (defun LM:Inters2Circle (c1 r1 c2 r2 / n d1 x z)
  204.   (if
  205.     (and
  206.       (< (setq d1 (distance c1 c2)) (+ r1 r2))
  207.       (< (abs (- r1 r2)) d1)
  208.     )
  209.     (progn
  210.       (setq n  (mapcar '- c2 c1)
  211.             c1 (trans c1 0 n)
  212.             z  (/ (- (+ (* r1 r1) (* d1 d1)) (* r2 r2)) (+ d1 d1))
  213.       )
  214.       (if (equal z r1 1e-8)
  215.         (list (trans (list (car c1) (cadr c1) (+ (caddr c1) z)) n 0))
  216.         (progn
  217.           (setq x (sqrt (- (* r1 r1) (* z z))))
  218.           (list
  219.               (trans (list (- (car c1) x) (cadr c1) (+ (caddr c1) z)) n 0)
  220.               (trans (list (+ (car c1) x) (cadr c1) (+ (caddr c1) z)) n 0)
  221.           )
  222.         )
  223.       )
  224.     )
  225.   )
  226. )
  227.  
  228. (defun member-fuzz (el lst fuzz)
  229.   (vl-member-if '(lambda (x) (equal x el fuzz)) lst)
  230. )
  231.  
  232. (defun AssocOn ( SearchTerm Lst func fuzz )
  233.   (car
  234.     (vl-member-if
  235.       (function
  236.         (lambda (pair) (equal SearchTerm (apply func (list pair)) fuzz))
  237.       )
  238.       lst
  239.     )
  240.   )
  241. )
  242.  
  243. (defun _sortol (pt lst)
  244.   (setq oll (cons (setq pt (NearestFromPoint lst pt)) oll))
  245.   (if (setq lst (vl-remove pt lst)) (_sortol pt lst) (reverse oll))
  246. )
  247.  
  248. (defun NearestFromPoint (lst pt / d1 d2 p1 p2)
  249.   (setq lst (vl-remove pt lst))
  250.   (setq d1 (distance pt (car lst))
  251.         p1 (car lst)
  252.   )
  253.   (foreach p2 (cdr lst)
  254.     (if (> d1 (setq d2 (distance pt p2)))
  255.         (setq d1 d2 p1 p2)
  256.     )
  257.   )
  258.   p1
  259. )
  260.  
  261. (defun mid (p1 p2)
  262.   (mapcar '(lambda (a b) (/ (+ a b) 2.0)) p1 p2)
  263. )
  264.  
  265. (defun otr (tr / p1 p2 p3 p12 p23 p31 o)
  266.   (setq p1 (car tr)
  267.         p2 (cadr tr)
  268.         p3 (caddr tr)
  269.   )
  270.   (setq p12 (mid p1 p2)
  271.         p23 (mid p2 p3)
  272.         p31 (mid p3 p1)
  273.   )
  274.   (setq o (inters p12 (mapcar '+ p12 (polar '(0.0 0.0 0.0) (+ (angle p1 p2) (* pi 0.5)) 1.0)) p23 (mapcar '+ p23 (polar '(0.0 0.0 0.0) (+ (angle p2 p3) (* pi 0.5)) 1.0)) nil))
  275.   o
  276. )
  277.  
  278. (defun getcircumcircle (a el / b c c2 cp r ang)
  279.   (setq b  (car el)
  280.         c  (cadr el)
  281.         c2 (list (car c) (cadr c))
  282.   )
  283.   (if (not
  284.         (zerop
  285.           (setq ang (- (angle b c) (angle b a)))
  286.         )
  287.       )
  288.     (progn (setq cp (polar c2
  289.                            (+ -1.570796326794896 (angle c a) ang)
  290.                            (setq r (/ (distance a c2) (sin ang) 2.0))
  291.                     )
  292.                  r  (abs r)
  293.            )
  294.            (list (+ (car cp) r) cp r a b c)
  295.     )
  296.   )
  297. )
  298.  

Regards, M.R.
« Last Edit: August 09, 2013, 12:26:24 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3257
  • Marko Ribar, architect
Re: ==={Challenge}=== Vonoroi diagram
« Reply #6 on: August 08, 2013, 05:23:57 PM »
Also slower, but the most correct... It did now for 50 pts...

So here is FINAL CODE :

Code - Auto/Visual Lisp: [Select]
  1. (defun c:test (/ i s)
  2.   (princ (strcat "\n select points"))
  3.   (if (setq i 0
  4.             s (ssget '((0 . "POINT")))
  5.       )
  6.       (repeat (sslength s)
  7.         (setq pl (cons (cdr (assoc 10 (entget (ssname s i)))) pl)
  8.               i  (1+ i)
  9.         )
  10.       )
  11.   )
  12.   (triangulate pl)
  13. )
  14.  
  15. (defun triangulate (pl / a b c i i1 i2 bb sl al el tl l ma mi tr x1 x2
  16.                     y1 y2 p r cp ol rl orl ss li oo o1 o2 r1 r2 in pll)
  17.  
  18.   (if pl
  19.     (progn
  20.       (setq
  21.         pll pl
  22.         i  1
  23.         i1 (/ (length pl) 100.)
  24.         i2 0
  25.         pl (vl-sort pl
  26.                     (function (lambda (a b) (< (car a) (car b))))
  27.            )
  28.         bb (list (apply 'mapcar (cons 'min pl))
  29.                  (apply 'mapcar (cons 'max pl))
  30.            )
  31.  
  32.         x1 (caar bb)
  33.         x2 (caadr bb)
  34.         y1 (cadar bb)
  35.         y2 (cadadr bb)
  36.  
  37.  
  38.       )
  39.       (setq cp (list (/ (+ x1 x2) 2.0) (/ (+ y1 y2) 2.0))
  40.             r  (* (distance cp (list x1 y1)) 20)
  41.             ma (+ (car cp) r)
  42.             mi (- (car cp) r)
  43.             sl (list (list ma (cadr cp) 0)
  44.                      (list mi (+ (cadr cp) r) 0)
  45.                      (list mi (- (cadr cp) r) 0)
  46.                )
  47.  
  48.             al (list (cons x2 (cons cp (cons (* 20 r) sl))))
  49.  
  50.             ma (1- ma)
  51.             mi (1+ mi)
  52.       )
  53.  
  54.       (repeat (length pl)
  55.  
  56.         (setq p  (car pl)
  57.               pl (cdr pl)
  58.               el nil
  59.         )
  60.         (while al
  61.           (setq tr (car al)
  62.                 al (cdr al)
  63.           )
  64.           (cond
  65.             ((< (car tr) (car p)) (setq tl (cons (cdddr tr) tl)))
  66.             ((< (distance p (cadr tr)) (caddr tr))
  67.              (setq tr (cdddr tr)
  68.                    a  (car tr)
  69.                    b  (cadr tr)
  70.                    c  (caddr tr)
  71.                    el (cons (list (+ (car a) (car b))
  72.                                   (+ (cadr a) (cadr b))
  73.                                   a
  74.                                   b
  75.                             )
  76.                             (cons (list (+ (car b) (car c))
  77.                                         (+ (cadr b) (cadr c))
  78.                                         b
  79.                                         c
  80.                                   )
  81.                                   (cons (list (+ (car c) (car a))
  82.                                               (+ (cadr c) (cadr a))
  83.                                               c
  84.                                               a
  85.                                         )
  86.                                         el
  87.                                   )
  88.                             )
  89.                       )
  90.  
  91.              )
  92.             )
  93.             (t (setq l (cons tr l)))
  94.           )
  95.         )
  96.  
  97.         (setq al l
  98.               l  nil
  99.  
  100.               el (vl-sort el
  101.                           (function (lambda (a b)
  102.                                       (if (= (car a) (car b))
  103.                                         (<= (cadr a) (cadr b))
  104.                                         (< (car a) (car b))
  105.                                       )
  106.                                     )
  107.                           )
  108.                  )
  109.         )
  110.  
  111.         (while el
  112.           (if (and (= (caar el) (caadr el))
  113.                    (= (cadar el) (cadadr el))
  114.               )
  115.             (setq el (cddr el))
  116.             (setq al (cons (getcircumcircle p (cddar el)) al)
  117.                   el (cdr el)
  118.             )
  119.           )
  120.         )
  121.       )
  122.  
  123.       (foreach tr al (setq tl (cons (cdddr tr) tl)))
  124.  
  125.       (setq
  126.         tl (vl-remove-if-not
  127.              (function
  128.                (lambda (a)
  129.                  (and (< mi (caadr a) ma) (< mi (caaddr a) ma))
  130.                )
  131.              )
  132.              tl
  133.            )
  134.       )
  135.  
  136.       (or (tblsearch "LAYER" "TIN")
  137.           (entmake (list
  138.                      '(0 . "LAYER")
  139.                      '(100 . "AcDbSymbolTableRecord")
  140.                      '(100 . "AcDbLayerTableRecord")
  141.                      '(2 . "TIN")         '(70 . 0)
  142.                      '(62 . 8)            '(6 . "Continuous")
  143.                      '(290 . 1)           '(370 . -3)
  144.                     )
  145.           )
  146.       )
  147.  
  148.       (or (tblsearch "LAYER" "Vonoroi")
  149.           (entmake (list
  150.                      '(0 . "LAYER")
  151.                      '(100 . "AcDbSymbolTableRecord")
  152.                      '(100 . "AcDbLayerTableRecord")
  153.                      '(2 . "Vonoroi")     '(70 . 0)
  154.                      '(62 . 1)            '(6 . "Continuous")
  155.                      '(290 . 1)           '(370 . -3)
  156.                     )
  157.           )
  158.       )
  159.  
  160.       (setvar "CLAYER" "TIN")
  161.  
  162.       (foreach tr tl
  163.         (entmake (list (cons 0 "3DFACE")
  164.                        (cons 10 (car tr))
  165.                        (cons 11 (car tr))
  166.                        (cons 12 (cadr tr))
  167.                        (cons 13 (caddr tr))
  168.                  )
  169.         )
  170.         (setq ol (cons (setq oo (otr tr)) ol))
  171.         (setq rl (cons (distance oo (car tr)) rl))
  172.       )
  173.  
  174.       (setq orl (mapcar '(lambda (a b) (cons a b)) ol rl))
  175.  
  176.       (foreach o1 ol
  177.         (foreach o2 (vl-remove o1 ol)
  178.           (entmake (list '(0 . "LINE") '(8 . "Vonoroi") (cons 10 o1) (cons 11 o2)))
  179.         )
  180.       )
  181.      
  182.       (setq ss (ssget "_X" '((0 . "LINE") (8 . "Vonoroi"))))
  183.       (command "_.-overkill" ss "" "")
  184.       (setq ss (ssget "_X" '((0 . "LINE") (8 . "Vonoroi"))))
  185.       (setq i -1)
  186.       (while (setq li (ssname ss (setq i (1+ i))))
  187.         (setq o1 (cdr (assoc 10 (entget li)))
  188.               o2 (cdr (assoc 11 (entget li)))
  189.         )
  190.         (setq r1 (cdr (assocon o1 orl 'car 1e-6))
  191.               r2 (cdr (assocon o2 orl 'car 1e-6))
  192.         )
  193.         (setq in (LM:Inters2Circle o1 r1 o2 r2))
  194.         (if (not (and in (member-fuzz (car in) pll 1e-6) (member-fuzz (cadr in) pll 1e-6))) (entdel li))
  195.       )
  196.      
  197.     )
  198.   )
  199.   (princ)
  200. )
  201.  
  202.  
  203. (defun LM:Inters2Circle (c1 r1 c2 r2 / n d1 x z)
  204.   (if
  205.     (and
  206.       (< (setq d1 (distance c1 c2)) (+ r1 r2))
  207.       (< (abs (- r1 r2)) d1)
  208.     )
  209.     (progn
  210.       (setq n  (mapcar '- c2 c1)
  211.             c1 (trans c1 0 n)
  212.             z  (/ (- (+ (* r1 r1) (* d1 d1)) (* r2 r2)) (+ d1 d1))
  213.       )
  214.       (if (equal z r1 1e-8)
  215.         (list (trans (list (car c1) (cadr c1) (+ (caddr c1) z)) n 0))
  216.         (progn
  217.           (setq x (sqrt (- (* r1 r1) (* z z))))
  218.           (list
  219.               (trans (list (- (car c1) x) (cadr c1) (+ (caddr c1) z)) n 0)
  220.               (trans (list (+ (car c1) x) (cadr c1) (+ (caddr c1) z)) n 0)
  221.           )
  222.         )
  223.       )
  224.     )
  225.   )
  226. )
  227.  
  228. (defun member-fuzz (el lst fuzz)
  229.   (vl-member-if '(lambda (x) (equal x el fuzz)) lst)
  230. )
  231.  
  232. (defun AssocOn ( SearchTerm Lst func fuzz )
  233.   (car
  234.     (vl-member-if
  235.       (function
  236.         (lambda (pair) (equal SearchTerm (apply func (list pair)) fuzz))
  237.       )
  238.       lst
  239.     )
  240.   )
  241. )
  242.  
  243. (defun mid (p1 p2)
  244.   (mapcar '(lambda (a b) (/ (+ a b) 2.0)) p1 p2)
  245. )
  246.  
  247. (defun otr (tr / p1 p2 p3 p12 p23 p31 o)
  248.   (setq p1 (car tr)
  249.         p2 (cadr tr)
  250.         p3 (caddr tr)
  251.   )
  252.   (setq p12 (mid p1 p2)
  253.         p23 (mid p2 p3)
  254.         p31 (mid p3 p1)
  255.   )
  256.   (setq o (inters p12 (mapcar '+ p12 (polar '(0.0 0.0 0.0) (+ (angle p1 p2) (* pi 0.5)) 1.0)) p23 (mapcar '+ p23 (polar '(0.0 0.0 0.0) (+ (angle p2 p3) (* pi 0.5)) 1.0)) nil))
  257.   o
  258. )
  259.  
  260. (defun getcircumcircle (a el / b c c2 cp r ang)
  261.   (setq b  (car el)
  262.         c  (cadr el)
  263.         c2 (list (car c) (cadr c))
  264.   )
  265.   (if (not
  266.         (zerop
  267.           (setq ang (- (angle b c) (angle b a)))
  268.         )
  269.       )
  270.     (progn (setq cp (polar c2
  271.                            (+ -1.570796326794896 (angle c a) ang)
  272.                            (setq r (/ (distance a c2) (sin ang) 2.0))
  273.                     )
  274.                  r  (abs r)
  275.            )
  276.            (list (+ (car cp) r) cp r a b c)
  277.     )
  278.   )
  279. )
  280.  

The code is slightly shorter than previous, but it makes firstly all lines between all circumcenters... Then it removes unnecessary lines...

M.R. (I hope this is it)
 8-) 8-) 8-)
« Last Edit: August 09, 2013, 12:25:17 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ymg

  • Guest
Re: ==={Challenge}=== Vonoroi diagram
« Reply #7 on: August 09, 2013, 12:11:59 AM »
Marko,

If you get Evgeniy's triangulation as I modified it here http://www.theswamp.org/index.php?topic=9042.msg502041#msg502041

By the end of triangulation you have the triangle list tl and the edge list el as index into point list pl.

From this it should be a simple matter to follow the midpoint of each edges from edge to midpoint  of (reverse edge).

As you go you destroy el.

Here I attached the triangulation with index.

ymg

ribarm

  • Gator
  • Posts: 3257
  • Marko Ribar, architect
Re: ==={Challenge}=== Vonoroi diagram
« Reply #8 on: August 09, 2013, 03:28:02 PM »
I thought I improved speed, but it's the same... On my comp. it takes 25min for 500 pts...

Here is improved code, in second iteration of (foreach) loop, list is every next time little smaller and it's dependable of how many iterations passed in first iteration of (foreach) loop... :

Code - Auto/Visual Lisp: [Select]
  1. (defun c:test (/ i s)
  2.   (princ (strcat "\n select points"))
  3.   (if (setq i 0
  4.             s (ssget '((0 . "POINT")))
  5.       )
  6.       (repeat (sslength s)
  7.         (setq pl (cons (cdr (assoc 10 (entget (ssname s i)))) pl)
  8.               i  (1+ i)
  9.         )
  10.       )
  11.   )
  12.   (triangulate pl)
  13. )
  14.  
  15. (defun triangulate (pl / a b c i i1 i2 bb sl al el tl l ma mi tr x1 x2
  16.                     y1 y2 p r cp ol rl orl ss li oo o1 o1l o2 r1 r2 in pll)
  17.  
  18.   (if pl
  19.     (progn
  20.       (setq
  21.         pll pl
  22.         i  1
  23.         i1 (/ (length pl) 100.)
  24.         i2 0
  25.         pl (vl-sort pl
  26.                     (function (lambda (a b) (< (car a) (car b))))
  27.            )
  28.         bb (list (apply 'mapcar (cons 'min pl))
  29.                  (apply 'mapcar (cons 'max pl))
  30.            )
  31.  
  32.         x1 (caar bb)
  33.         x2 (caadr bb)
  34.         y1 (cadar bb)
  35.         y2 (cadadr bb)
  36.  
  37.  
  38.       )
  39.       (setq cp (list (/ (+ x1 x2) 2.0) (/ (+ y1 y2) 2.0))
  40.             r  (* (distance cp (list x1 y1)) 20)
  41.             ma (+ (car cp) r)
  42.             mi (- (car cp) r)
  43.             sl (list (list ma (cadr cp) 0)
  44.                      (list mi (+ (cadr cp) r) 0)
  45.                      (list mi (- (cadr cp) r) 0)
  46.                )
  47.  
  48.             al (list (cons x2 (cons cp (cons (* 20 r) sl))))
  49.  
  50.             ma (1- ma)
  51.             mi (1+ mi)
  52.       )
  53.  
  54.       (repeat (length pl)
  55.  
  56.         (setq p  (car pl)
  57.               pl (cdr pl)
  58.               el nil
  59.         )
  60.         (while al
  61.           (setq tr (car al)
  62.                 al (cdr al)
  63.           )
  64.           (cond
  65.             ((< (car tr) (car p)) (setq tl (cons (cdddr tr) tl)))
  66.             ((< (distance p (cadr tr)) (caddr tr))
  67.              (setq tr (cdddr tr)
  68.                    a  (car tr)
  69.                    b  (cadr tr)
  70.                    c  (caddr tr)
  71.                    el (cons (list (+ (car a) (car b))
  72.                                   (+ (cadr a) (cadr b))
  73.                                   a
  74.                                   b
  75.                             )
  76.                             (cons (list (+ (car b) (car c))
  77.                                         (+ (cadr b) (cadr c))
  78.                                         b
  79.                                         c
  80.                                   )
  81.                                   (cons (list (+ (car c) (car a))
  82.                                               (+ (cadr c) (cadr a))
  83.                                               c
  84.                                               a
  85.                                         )
  86.                                         el
  87.                                   )
  88.                             )
  89.                       )
  90.  
  91.              )
  92.             )
  93.             (t (setq l (cons tr l)))
  94.           )
  95.         )
  96.  
  97.         (setq al l
  98.               l  nil
  99.  
  100.               el (vl-sort el
  101.                           (function (lambda (a b)
  102.                                       (if (= (car a) (car b))
  103.                                         (<= (cadr a) (cadr b))
  104.                                         (< (car a) (car b))
  105.                                       )
  106.                                     )
  107.                           )
  108.                  )
  109.         )
  110.  
  111.         (while el
  112.           (if (and (= (caar el) (caadr el))
  113.                    (= (cadar el) (cadadr el))
  114.               )
  115.             (setq el (cddr el))
  116.             (setq al (cons (getcircumcircle p (cddar el)) al)
  117.                   el (cdr el)
  118.             )
  119.           )
  120.         )
  121.       )
  122.  
  123.       (foreach tr al (setq tl (cons (cdddr tr) tl)))
  124.  
  125.       (setq
  126.         tl (vl-remove-if-not
  127.              (function
  128.                (lambda (a)
  129.                  (and (< mi (caadr a) ma) (< mi (caaddr a) ma))
  130.                )
  131.              )
  132.              tl
  133.            )
  134.       )
  135.  
  136.       (or (tblsearch "LAYER" "TIN")
  137.           (entmake (list
  138.                      '(0 . "LAYER")
  139.                      '(100 . "AcDbSymbolTableRecord")
  140.                      '(100 . "AcDbLayerTableRecord")
  141.                      '(2 . "TIN")         '(70 . 0)
  142.                      '(62 . 8)            '(6 . "Continuous")
  143.                      '(290 . 1)           '(370 . -3)
  144.                     )
  145.           )
  146.       )
  147.  
  148.       (or (tblsearch "LAYER" "Vonoroi")
  149.           (entmake (list
  150.                      '(0 . "LAYER")
  151.                      '(100 . "AcDbSymbolTableRecord")
  152.                      '(100 . "AcDbLayerTableRecord")
  153.                      '(2 . "Vonoroi")     '(70 . 0)
  154.                      '(62 . 1)            '(6 . "Continuous")
  155.                      '(290 . 1)           '(370 . -3)
  156.                     )
  157.           )
  158.       )
  159.  
  160.       (setvar "CLAYER" "TIN")
  161.  
  162.       (foreach tr tl
  163.         (entmake (list (cons 0 "3DFACE")
  164.                        (cons 10 (car tr))
  165.                        (cons 11 (car tr))
  166.                        (cons 12 (cadr tr))
  167.                        (cons 13 (caddr tr))
  168.                  )
  169.         )
  170.         (setq ol (cons (setq oo (otr tr)) ol))
  171.         (setq rl (cons (distance oo (car tr)) rl))
  172.       )
  173.  
  174.       (setq orl (mapcar '(lambda (a b) (cons a b)) ol rl))
  175.  
  176.       (foreach o1 ol
  177.         (setq o1l (cons o1 o1l))
  178.         (setq r1 (cdr (assocon o1 orl 'car 1e-6)))
  179.         (foreach o2 (_reml ol o1l)
  180.           (setq r2 (cdr (assocon o2 orl 'car 1e-6)))
  181.           (setq in (LM:Inters2Circle o1 r1 o2 r2))
  182.           (if (and in (member-fuzz (car in) pll 1e-6) (member-fuzz (cadr in) pll 1e-6))
  183.             (entmake (list '(0 . "LINE") '(8 . "Vonoroi") (cons 10 o1) (cons 11 o2)))
  184.           )
  185.         )
  186.       )
  187.      
  188.       (setq ss (ssget "_X" '((0 . "LINE") (8 . "Vonoroi"))))
  189.       (command "_.-overkill" ss "" "")
  190.      
  191.     )
  192.   )
  193.   (princ)
  194. )
  195.  
  196. (defun _reml (l1 l2 / a n ls)
  197.   (while
  198.     (setq n nil
  199.           a (car l2)
  200.     )
  201.     (while (and l1 (null n))
  202.       (if (equal a (car l1) 1e-8)
  203.         (setq l1 (cdr l1)
  204.               n t
  205.         )
  206.         (setq ls (append ls (list (car l1)))
  207.               l1 (cdr l1)
  208.         )
  209.       )
  210.     )
  211.     (setq l2 (cdr l2))
  212.   )
  213.   (append ls l1)
  214. )
  215.  
  216. (defun LM:Inters2Circle (c1 r1 c2 r2 / n d1 x z)
  217.   (if
  218.     (and
  219.       (< (setq d1 (distance c1 c2)) (+ r1 r2))
  220.       (< (abs (- r1 r2)) d1)
  221.     )
  222.     (progn
  223.       (setq n  (mapcar '- c2 c1)
  224.             c1 (trans c1 0 n)
  225.             z  (/ (- (+ (* r1 r1) (* d1 d1)) (* r2 r2)) (+ d1 d1))
  226.       )
  227.       (if (equal z r1 1e-8)
  228.         (list (trans (list (car c1) (cadr c1) (+ (caddr c1) z)) n 0))
  229.         (progn
  230.           (setq x (sqrt (- (* r1 r1) (* z z))))
  231.           (list
  232.               (trans (list (- (car c1) x) (cadr c1) (+ (caddr c1) z)) n 0)
  233.               (trans (list (+ (car c1) x) (cadr c1) (+ (caddr c1) z)) n 0)
  234.           )
  235.         )
  236.       )
  237.     )
  238.   )
  239. )
  240.  
  241. (defun member-fuzz (el lst fuzz)
  242.   (vl-member-if '(lambda (x) (equal x el fuzz)) lst)
  243. )
  244.  
  245. (defun AssocOn ( SearchTerm Lst func fuzz )
  246.   (car
  247.     (vl-member-if
  248.       (function
  249.         (lambda (pair) (equal SearchTerm (apply func (list pair)) fuzz))
  250.       )
  251.       lst
  252.     )
  253.   )
  254. )
  255.  
  256. (defun mid (p1 p2)
  257.   (mapcar '(lambda (a b) (/ (+ a b) 2.0)) p1 p2)
  258. )
  259.  
  260. (defun otr (tr / p1 p2 p3 p12 p23 p31 o)
  261.   (setq p1 (car tr)
  262.         p2 (cadr tr)
  263.         p3 (caddr tr)
  264.   )
  265.   (setq p12 (mid p1 p2)
  266.         p23 (mid p2 p3)
  267.         p31 (mid p3 p1)
  268.   )
  269.   (setq o (inters p12 (mapcar '+ p12 (polar '(0.0 0.0 0.0) (+ (angle p1 p2) (* pi 0.5)) 1.0)) p23 (mapcar '+ p23 (polar '(0.0 0.0 0.0) (+ (angle p2 p3) (* pi 0.5)) 1.0)) nil))
  270.   o
  271. )
  272.  
  273. (defun getcircumcircle (a el / b c c2 cp r ang)
  274.   (setq b  (car el)
  275.         c  (cadr el)
  276.         c2 (list (car c) (cadr c))
  277.   )
  278.   (if (not
  279.         (zerop
  280.           (setq ang (- (angle b c) (angle b a)))
  281.         )
  282.       )
  283.     (progn (setq cp (polar c2
  284.                            (+ -1.570796326794896 (angle c a) ang)
  285.                            (setq r (/ (distance a c2) (sin ang) 2.0))
  286.                     )
  287.                  r  (abs r)
  288.            )
  289.            (list (+ (car cp) r) cp r a b c)
  290.     )
  291.   )
  292. )
  293.  

M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ymg

  • Guest
Re: ==={Challenge}=== Vonoroi diagram
« Reply #9 on: August 10, 2013, 12:39:23 PM »
Marko,

Here is my entry attached below as vor.lsp

Here I am only generating line segment.  I believe proper way would be to join
in LWpolyline to make region.

No recalc is needed as everything is already there as you triangulate.
Did not test thoroughly but seems OK.

See image below:

ymg

« Last Edit: August 10, 2013, 04:13:02 PM by ymg »

ribarm

  • Gator
  • Posts: 3257
  • Marko Ribar, architect
Re: ==={Challenge}=== Vonoroi diagram
« Reply #10 on: August 10, 2013, 02:13:43 PM »
ymg, thank you very much...

Your code works very fast, it did my 500 pts in ab 1-2 sec... You're really very generous for posting it... Still I've found some minor mistakes - in creating layer, and you omitted to supply pl argument for (trinagulate), and also (vl-load-com) for those that don't have it loaded every time - like myself... I am posting your code in code tags, just in case login isn't possible and in case someone sees something we didn't...

You are really great, routine rocks, and just to mention all points must be planar - must lie in WCS plane so your rnd generator isn't here the most appropriate...

Once again, thanks - even there is no need for (_.-overkill) everything is optimized just fine...

Code - Auto/Visual Lisp: [Select]
  1. (defun c:vor (/ i s pl doc)
  2.  
  3.  
  4.    (or doc
  5.    )
  6.  
  7.        (princ (strcat "\n Select points"))
  8.        (if (setq  i 0
  9.                  pl nil
  10.                   s (ssget '((0 . "POINT")))         
  11.            )
  12.            (progn
  13.               (if doc (vla-endundomark doc))
  14.               (repeat (sslength s)
  15.                  (setq pl (cons (cdr (assoc 10 (entget (ssname s i)))) pl)
  16.                         i (1+ i)
  17.                  )
  18.               )
  19.               (setq pl (vl-sort pl (function (lambda (a b) (< (car a) (car b))))))
  20.              ; Sorting of point list moved here so contour can use it.                      
  21.              
  22.              (triangulate pl)
  23.              
  24.           ); end progn
  25.        ); end if
  26.      
  27.       (vla-endundomark doc)
  28.    (princ)
  29. )
  30.  
  31.  
  32.  
  33.  
  34. ;;************************************************************************************************;
  35. ;; Triangulate                                                                                    ;
  36. ;; Structure of Program by  ElpanovEvgeniy                                                        ;
  37. ;; 17.10.2008                                                                                     ;
  38. ;; edit 20.05.2011                                                                                ;
  39. ;; Program triangulate an irregular set of 3d points.                                             ;
  40. ;; Modified and Commented by ymg          June 2011.                                              ;
  41. ;; Modified to operate on index by ymg in June 2013.                                              ;
  42. ;; Contour Generation added by ymg in     July 2013.                                              ;
  43. ;;************************************************************************************************;
  44.  
  45. (defun triangulate ( pl /   a al b  c cp  i i1 i2 l
  46.                             n  p r  ti tr
  47.                             xmax xmin ymax ymin  
  48.                    )
  49.    
  50.    (if pl
  51.       (progn
  52.          (setq ti (car (_VL-TIMES));Initialize timer for Triangulation                            
  53.                
  54.                 i  1
  55.                i1 (/ (length pl) 100.)
  56.                i2 0
  57.                ; Variables and Constant to Control Progress Spinner                                
  58.                tl nil
  59.                
  60.                pl (vl-sort pl
  61.                      (function (lambda (a b) (< (car a) (car b))))
  62.                   )
  63.                ; Sort points list on x coordinates                                                
  64.                
  65.                bb (list (apply 'mapcar (cons 'min pl))
  66.                         (apply 'mapcar (cons 'max pl))
  67.                   )
  68.                ;Replaced code to get the min and max with 3d Bounding Box Routine                  
  69.                ;A bit slower but clearer. zmin and zmax kept for contouring                        
  70.                
  71.                xmin (caar bb)      
  72.                xmax (caadr bb)      
  73.                ymin (cadar bb)      
  74.                ymax (cadadr bb)      
  75.                  np (length pl) ;Number of points to insert                                        
  76.                
  77.                  cp (list (/ (+ xmin xmax) 2.0) (/ (+ ymin ymax) 2.0))
  78.                ; Midpoint of points cloud and center point of circumcircle through supertriangle.  
  79.                   r (* (distance cp (list xmin ymin)) 20)
  80.                ; This could still be too small in certain case. No harm if we make it bigger.      
  81.                
  82.                 sl (list
  83.                         (list (+ (car cp) r) (cadr cp) 0)          
  84.                         (list (- (car cp) r) (+ (cadr cp) r) 0)    
  85.                         (list (- (car cp) r) (- (cadr cp) r) 0)
  86.                   )
  87.                ; sl list of 3 points defining the Supertriangle,                                  
  88.                ; I have tried initializing to an infinite triangle but it slows down calculation  
  89.                pl (append pl sl)
  90.                ;Vertex of Supertriangle are appended to the Point list                            
  91.                sl (list np (+ np 1)(+ np 2))
  92.                ;sl now is a list of index into point list defining the supertriangle              
  93.                
  94.                al  (list(list xmax cp r sl))
  95.               ;Initialize the Active Triangle list                                                
  96.               ; al is a  list that contains active triangles defined by 4 items:                  
  97.               ;     item 0: Xmax of points in triangle.                                            
  98.               ;     item 1: List 2d coordinates of center of circle circumscribing triangle.      
  99.               ;     item 2: Radius of above circle.                                                
  100.               ;     item 3: List of 3 indexes to vertices defining the triangle                    
  101.               ctr (list cp)   ;added for Voronoi       
  102.                n -1
  103.               ; n is a counting index into Point List                                              
  104.          )              
  105.  
  106.          
  107.          ;Begin insertion of points
  108.          
  109.          (repeat np
  110.            
  111.             (setq  n (1+ n)     ; Increment Index into Point List                                  
  112.                    p (nth n pl) ; Get one point from point list                                    
  113.                   el nil        ; el list of triangles edges                                      
  114.             )                   ;                                                                  
  115.             (repeat (length al) ; Loop to go through Active triangle list                          
  116.                (setq tr (car al); Get one triangle from active triangle list.                      
  117.                      al (cdr al); Remove the triangle from the active list.                        
  118.                )
  119.                (cond
  120.                   ((< (car tr) (car p)) (setq tl (cons (cadddr tr) tl)
  121.                                               ctr (cons (cadr tr) ctr); added for voronoi            
  122.                                         )
  123.                   )
  124.                   ;This triangle inactive. We store it's 3 vertex in tl (Final triangle list).    
  125.                  
  126.                   ((< (distance p (cadr tr)) (caddr tr)) ; p is inside the triangle.              
  127.                    (setq tr (cadddr tr)                  ; Trim tr to vertex of triangle only.    
  128.                           a (car tr)                     ;  Index of First point.                  
  129.                           b (cadr tr)                    ;  Index of Second point.                
  130.                           c (caddr tr)                   ;  Index of Third point.                  
  131.                          el (cons (list a                ; ((a b)(b c)(c a) (. .)(. .).....)      
  132.                                         b
  133.                                   )
  134.                                   (cons (list b
  135.                                               c
  136.                                         )
  137.                                         (cons (list c
  138.                                                     a
  139.                                               )
  140.                                               el
  141.                                         )
  142.                                   )
  143.                             )
  144.                            
  145.                    )
  146.                   )
  147.                   (t (setq l (cons tr l)))
  148.                   ;tr did not meet any cond so it remain active. We store it in the swap list      
  149.                );End cond
  150.              
  151.             );End repeat (length al)
  152.            
  153.            
  154.             (setq al l    ;Restore active triangle list from the temporary list.                  
  155.                    l nil  ;Clear the swap list to prepare for next insertion.                      
  156.             )
  157.            
  158.             ;Removes doubled edges, calculates circumcircles and add them to al
  159.            
  160.             (while el
  161.                (if (or (member (reverse (car el)) el)
  162.                        (member (car el) (cdr el))
  163.                    )
  164.                    (setq el (vl-remove (reverse (car el)) el)
  165.                          el (vl-remove (car el) el)
  166.                    )
  167.                    (setq al (cons (getcircumcircle n (car el) pl) al)
  168.                          el (cdr el)
  169.                   )
  170.                )
  171.             )
  172.            
  173.             ; Neat Progress Spinner                                                                
  174.             (if (and (< (setq i (1- i)) 1) (< i2 100))
  175.                (progn
  176.                   (setvar
  177.                      "MODEMACRO"
  178.                      (strcat
  179.                         "     "
  180.                         (itoa (setq i2 (1+ i2)))
  181.                         " %    "
  182.                         (substr
  183.                            "||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"
  184.                            1
  185.                            i2
  186.                         )
  187.                         (substr "..." 1 (- 100 i2))
  188.                      )
  189.                   )
  190.                   (setq i i1)
  191.                )
  192.             )
  193.          
  194.          ) ;End repeat np
  195.          
  196.          
  197.          ;We are done with points insertion. Any triangle left in al is added to tl               ;
  198.          
  199.          (foreach tr al (setq  tl (cons (cadddr tr) tl)
  200.                               ctr (cons (cadr tr) ctr)  ; Added for Voronoi
  201.                         )
  202.  
  203.          )
  204.  
  205.          ; Extract all triangle edges from tl and form edges list el                                    
  206.          (setq el nil)
  207.          (foreach tr tl
  208.               (setq el (cons (list (car tr)(cadr tr)) el)
  209.                     el (cons (list (cadr tr)(caddr tr)) el)
  210.                     el (cons (list (caddr tr)(car tr)) el)
  211.               )
  212.          )
  213.          (setq el (reverse el))
  214.  
  215.  
  216.        
  217.          ; Here  let's draw the Voronoi Diagram                                                   ;
  218.          (setq vl nil)
  219.          (foreach e el
  220.              (setq  npos (vl-position (reverse e) el)
  221.                     epos (vl-position e el)
  222.                      
  223.              )
  224.              (if npos
  225.                 (setq vl (cons (list (/ npos 3) (/ epos 3)) vl))
  226.                 (setq vl (cons (list (- (length ctr) 1) (/ epos 3)) vl))
  227.              )
  228.          )
  229.          (setq vor nil)
  230.          (while vl
  231.               (setq   e (car vl)
  232.                      vl (vl-remove (reverse e) (cdr vl))
  233.                     vor (cons  e vor)
  234.               )      
  235.          )
  236.        
  237.          (setq vor (vl-sort vor (function (lambda (a b) (> (car a) (car b)))))
  238.                vor (cdddr vor) ; Remove the edges of Supercircle              ;
  239.          )
  240.        
  241.          ; Creates Layer for Voronoi Diagram                                  
  242.          (or (tblsearch "LAYER" "Voronoi")
  243.             (entmake (list
  244.                         '(0 . "LAYER")
  245.                         '(100 . "AcDbSymbolTableRecord")
  246.                         '(100 . "AcDbLayerTableRecord")
  247.                         '(2 . "Voronoi")
  248.                         '(70 . 0)
  249.                         '(62 . 10)
  250.                         '(6 . "Continuous")
  251.                         '(290 . 1)
  252.                         '(370 . -3)
  253.                      )
  254.              )
  255.          )
  256.          
  257.          (setvar "CLAYER" "Voronoi")
  258.        
  259.          (foreach v vor
  260.              (setq ent nil
  261.                    ent (cons (cons 11 (nth (car v) ctr))ent)
  262.                    ent (cons (cons 10 (nth (cadr v) ctr))ent)
  263.                    ent (cons (cons 8 "Voronoi") ent)
  264.                    ent (cons (cons 0 "LINE") ent)
  265.              )
  266.              (entmake ent)
  267.          )
  268.  
  269.  
  270.         ; Purge triangle list of any triangle that has a common vertex with supertriangle.             ;
  271.    
  272.          (setq tl (vl-remove-if-not
  273.                      (function
  274.                         (lambda (a) (and (< (car a) np)(< (cadr a) np)(< (caddr a) np)))
  275.                      )
  276.                      tl
  277.                   )
  278.          )
  279.      
  280.          ;Create a layer and Draw the triangulation                                                
  281.          (or (tblsearch "LAYER" "TIN")
  282.             (entmake (list
  283.                         '(0 . "LAYER")
  284.                         '(100 . "AcDbSymbolTableRecord")
  285.                         '(100 . "AcDbLayerTableRecord")
  286.                         '(2 . "TIN")
  287.                         '(70 . 0)
  288.                         '(62 . 8)
  289.                         '(6 . "Continuous")
  290.                         '(290 . 1)
  291.                         '(370 . -3)
  292.                      )
  293.              )
  294.          )
  295.          
  296.          (setvar "CLAYER" "TIN")         
  297.          (foreach tr tl
  298.             (entmake (list (cons 0 "3DFACE")
  299.                            (cons 10 (nth (car tr)   pl))
  300.                            (cons 11 (nth (car tr)   pl))
  301.                            (cons 12 (nth (cadr tr)  pl))
  302.                            (cons 13 (nth (caddr tr) pl))
  303.                      )
  304.             )
  305.          )
  306.       )
  307.    )
  308.    (setvar "MODEMACRO" "")
  309.  
  310.    
  311.  
  312.    (princ (strcat "\n     TIN - Elapsed time: " (rtos (/ (- (car (_VL-TIMES)) ti) 1000.) 2 4) " secs, "
  313.                    (itoa (length tl)) " 3DFACES"
  314.           )      
  315.    )
  316.  
  317. )  
  318.  
  319.  
  320.  
  321. ;;************************************************************************************************;
  322. ;;                                                                                                ;
  323. ;; Written by  ElpanovEvgeniy                                                                     ;
  324. ;; 17.10.2008                                                                                     ;
  325. ;; Calculation of the centre of a circle and circle radius                                        ;
  326. ;; for program triangulate                                                                        ;
  327. ;;                                                                                                ;
  328. ;; Modified ymg june 2011 (renamed variables)                                                     ;
  329. ;; Modified ymg June 2013 to operate on Index                                                     ;
  330. ;;************************************************************************************************;
  331.  
  332. (defun getcircumcircle (a el pl /  b c c2 cp r ang vl p)
  333.    
  334.    (setq p (nth a pl)
  335.          b (nth(car el) pl)
  336.          c (nth(cadr el) pl)
  337.         c2 (list (car c) (cadr c)) ;c2 is point c but in 2d                                        
  338.         vl (list a (car el) (cadr el))
  339.    )
  340.    (if (not
  341.           (zerop
  342.              (setq ang (- (angle b c) (angle b p)))
  343.           )
  344.        )
  345.       (progn (setq cp (polar c2
  346.                           (+ -1.570796326794896 (angle c p) ang)
  347.                           (setq r (/ (distance p c2) (sin ang) 2.0))
  348.                       )
  349.                     r (abs r)
  350.              )
  351.              (list (+ (car cp) r) cp r vl)
  352.       )
  353.    )
  354. )
  355.  
  356.  
  357. ; Midpoint of two points                                                                          
  358. (defun mid (a b)         
  359.      (mapcar '(lambda (a b) (/ (+ a b) 2.0)) a b)
  360. )
  361.  
  362.  
  363.  
  364. ; Generate a bunch of points for testing on layer named points.                                    
  365. ; This function change Autocad vars PDMODE to 34 and PDSIZE to -1.5                                
  366. (
  367.  defun c:gen ( / n rangex rangey rangez)
  368.        
  369.         (setq n (getint "\nNumber of points: ")
  370.               rangex 5000          ; Extent in X for the points                                    
  371.               rangey (/ rangex 1.6); Extent in Y * Golden Ratio                                    
  372.               rangez 20            ; Extent in Z                                                  
  373.         )
  374.  
  375.        
  376.        
  377.         (while (> n 0)
  378.                 (entmake
  379.                     (list
  380.                        '(0 . "POINT")
  381.                        '(8 . "Points")
  382.                         (cons 10 (list (* rangex (ran)) (* rangey (ran)) (* rangez (ran))))
  383.                     )
  384.                 )
  385.                 (setq n (1- n))
  386.         )
  387.         (command "ZOOM" "E")
  388.         (command "ZOOM" "0.85x")
  389.         (setvar "PDMODE" 34)     ; You will need to set it back to your preference manually.      
  390.         (setvar "PDSIZE" -1.5)   ; 1.5 Percent relative to screen.                                
  391. )
  392. ; Random number generator                                                                          
  393. (defun ran ()
  394.     (setq seed (if seed (rem (+ (* seed 15625.7) 0.21137152) 1) 0.3171943))
  395. )
  396.  

BTW. I think it's called "Vonoroi" and not "Voronoi", but I don't quite know, just when google-ing, www recognizes "Vonoroi"

M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ymg

  • Guest
Re: ==={Challenge}=== Vonoroi diagram
« Reply #11 on: August 10, 2013, 03:27:57 PM »
Marko,

Quote
Still I've found some minor mistakes - in creating layer, and you omitted to supply pl argument for (trinagulate),

I have corrected the attachment on post above.

Unless I am getting dyslexic I believe Voronoi is correct from Wikipedia.

Quote
Georgy Feodosevich Voronoy (Ukrainian: Георгій Феодосійович Вороний; Russian: Гео́ргий Феодо́сьевич Вороно́й; 28 April 1868 – 20 November 1908) was a Ukrainian and Russian mathematician. Among other things, he defined the Voronoi diagram.

As I told you above everything is already there once you have the triangulation.  I simply join the circumcircle of every triangle with a
line segment.  Could be made faster by not re-creating the list of center, but was lazy.

As for the generosity I am a strong believer that knowledge should be shared.  Did not invent anything here simply coded it.

ymg

ribarm

  • Gator
  • Posts: 3257
  • Marko Ribar, architect
Re: ==={Challenge}=== Vonoroi diagram
« Reply #12 on: August 11, 2013, 01:20:56 PM »
Here I am only generating line segment.  I believe proper way would be to join
in LWpolyline to make region.

No need to create LWpolyline to make regions, just use REGION command on created lines, and if you want to convert these regions to LWpolylines, try this my code (only thing it's slow when dealing with too much regions - it converted 5000 regions to LWpolylines on my comp. for ab 20min). I believe this can't be much faster...

Code: [Select]
(defun unit ( v )
  (mapcar '(lambda ( x ) (/ x (distance '(0.0 0.0 0.0) v))) v)
)

(defun mxv ( m v )
  (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
)

(defun v^v ( u v )
  (list
    (- (* (cadr u) (caddr v)) (* (cadr v) (caddr u)))
    (- (* (car  v) (caddr u)) (* (car  u) (caddr v)))
    (- (* (car  u) (cadr  v)) (* (car  v) (cadr  u)))
  )
)

(defun transptucs ( pt p1 p2 p3 / ux uy uz )
  (setq uz (unit (v^v (mapcar '- p2 p1) (mapcar '- p3 p1))))
  (setq ux (unit (mapcar '- p2 p1)))
  (setq uy (unit (mapcar '- p3 p1)))
 
  (mxv (list ux uy uz) (mapcar '- pt p1))
)

(defun transptwcs ( pt pt1 pt2 pt3 / pt1n pt2n pt3n )
  (setq pt1n (transptucs '(0.0 0.0 0.0) pt1 pt2 pt3))
  (setq pt2n (transptucs '(1.0 0.0 0.0) pt1 pt2 pt3))
  (setq pt3n (transptucs '(0.0 1.0 0.0) pt1 pt2 pt3))
  (transptucs pt pt1n pt2n pt3n)
)

(defun entmakelwpoly3dpts ( ptlst opclflag / ux uy uz uptlst )
  (setq uz (unit (v^v (mapcar '- (cadr ptlst) (car ptlst)) (mapcar '- (caddr ptlst) (car ptlst)))))
  (if (equal uz '(0.0 0.0 1.0) 1e-8) (setq ux '(1.0 0.0 0.0) uy '(0.0 1.0 0.0)))
  (if (equal uz '(0.0 0.0 -1.0) 1e-8) (setq ux '(-1.0 0.0 0.0) uy '(0.0 1.0 0.0)))
  (if (not (or (equal uz '(0.0 0.0 1.0) 1e-8) (equal uz '(0.0 0.0 -1.0) 1e-8))) (setq ux (unit (v^v '(0.0 0.0 1.0) uz))))
  (if (not uy) (setq uy (unit (v^v uz ux))))
  (setq uptlst (mapcar '(lambda ( p ) (transptucs p '(0.0 0.0 0.0) ux uy)) ptlst))
  (entmake
    (append
      (list
        '(0 . "LWPOLYLINE")
        '(100 . "AcDbEntity")
        '(100 . "AcDbPolyline")
        (cons 90 (length uptlst))
        (cons 70 opclflag)
        '(62 . 3)
        (cons 38 (caddar uptlst))
      )
      (mapcar '(lambda ( x ) (list 10 (car x) (cadr x))) uptlst)
      (list (cons 210 uz))
    )
  )
  (princ)
)

(defun AssocOn ( SearchTerm Lst func fuzz )
  (car
    (vl-member-if
      (function
        (lambda (pair) (equal SearchTerm (apply func (list pair)) fuzz))
      )
      lst
    )
  )
)

(defun plptlstss ( ss / i li p1 p2 lipts lilst )
  (setq i -1)
  (while (setq li (ssname ss (setq i (1+ i))))
    (setq p1 (cdr (assoc 10 (entget li)))
          p2 (cdr (assoc 11 (entget li)))
    )
    (setq lipts nil)
    (setq lipts (cons p1 lipts) lipts (cons p2 lipts))
    (setq lilst (cons lipts lilst))
  )
  lilst
)

(defun plptlstlilst ( lst / p1 p2 asp2 )
  (setq p1 (caar lst)
        p2 (cadar lst)
  )
  (setq plptlst (cons p1 plptlst) plptlst (cons p2 plptlst))
  (setq lst (cdr lst))
  (if (setq asp2 (assocon p2 lst 'car 1e-6)) (setq lst (cons asp2 (vl-remove asp2 lst))))
  (if (setq asp2 (assocon p2 lst 'cadr 1e-6)) (setq lst (cons (reverse asp2) (vl-remove asp2 lst))))
  (if lst (plptlstlilst lst) plptlst)
)

(defun c:regs2pls ( / ss i reg el ssel pllst ii li )
  (vl-load-com)
  (setq ss (ssget '((0 . "REGION"))))
  (setq i -1)
  (while (setq reg (ssname ss (setq i (1+ i))))
    (setq el (entlast))
    (vla-explode (vlax-ename->vla-object reg))
    (while (setq el (entnext el))
      (setq ssel (acet-ss-union (list ssel (ssadd el))))
    )
    (setq pllst (acet-list-remove-duplicates (plptlstlilst (plptlstss ssel)) 1e-6))
    (setq ii -1)
    (while (setq li (ssname ssel (setq ii (1+ ii))))
      (entdel li)
    )
    (entmakelwpoly3dpts pllst 1)
    (setq plptlst nil ssel nil)
  )
  (princ)
)

M.R.
« Last Edit: September 20, 2013, 04:33:38 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

mailmaverick

  • Bull Frog
  • Posts: 493
Re: ==={Challenge}=== Vonoroi diagram
« Reply #13 on: March 26, 2017, 01:10:26 PM »
Marko,

Here is my entry attached below as vor.lsp

Here I am only generating line segment.  I believe proper way would be to join
in LWpolyline to make region.

No recalc is needed as everything is already there as you triangulate.
Did not test thoroughly but seems OK.

See image below:

ymg



Hi YMG,

Thanks for your excellent LISP. Is it possible to trim (or clip) the Voronoi Polygons about a selected Boundary (Closed Polyline).