Author Topic: Poisson Disk Sampling - Bridson Algorithm - Blue Noise  (Read 11650 times)

0 Members and 1 Guest are viewing this topic.

ymg

  • Guest
Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« on: September 24, 2013, 01:17:48 PM »
Here is a function for generating a Random Point Set with a minimum spacing between them.

Function is for 2d but could be extended to any dimension although this becomes very memory intensive.

Could be used for spacing block or whatever.

Some links to papers or articles:  Fast Poisson Disk Sampling in Arbitrary Dimensions at UBC by Robert Bridson.
                                                  Poisson Disk Sampling on Devmag by Herman Tulleken.


ymg

Here is the code:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ()
  2.              
  3.           (setq exty (getvar 'viewsize)
  4.                 extx (* exty  1.6180) ;(* exty (apply '/ (getvar 'screensize)))
  5.                   sp (/ extx 60)
  6.           )
  7.           (command "._ZOOM" "_C" (list (/ extx 2) (/ exty 2)) (* 0.75 exty))
  8.           (bridson extx exty sp)
  9.      
  10.      (princ)
  11. )
  12.  
  13. ;; Poisson Disk Sampling per Bridson Algorithm                                ;
  14. ;;                                                                            ;
  15. ;; See: http://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf;
  16. ;;      http://devmag.org.za/2009/05/03/poisson-disk-sampling/                ;
  17. ;;                                                                            ;
  18. ;; Will return a Random Set of points with a minimum distance between them    ;
  19.  
  20. (defun bridson (width height mindist / a al cells cellsize grid i ind k p p1 p2 pl r tcl  x y)
  21.     (setq        k 30
  22.           cellSize (/ mindist (sqrt 2))
  23.                  x (ceil (/ width cellsize))
  24.                  y (ceil (/ height cellsize))
  25.                
  26.               grid (vlax-make-safearray vlax-vbInteger (cons 0 x)(cons 0 y))
  27.                 p1 (list (rand width)(rand height))
  28.                 ;z (* (PerlinNoise (car p1) (cadr p1)) 10)
  29.                 pl (list (list (car p1) (cadr p1) 0.0))
  30.                 al (list 0)  ; Initialize Active List with index of First Point;
  31.                ind (mapcar '(lambda (a) (fix (/ a cellsize))) p1)
  32.                  
  33.     )
  34.     (init2d grid x y  )      ; Initialize the grid to all -1, then             ;
  35.                              ; Put index of First Point in Grid                ;
  36.     (vlax-safearray-put-element grid (car ind) (cadr ind) 0)
  37.      
  38.     (setq i 0) 
  39.     (while al
  40.         (setq   p (nth (fix (rand (length al))) al)
  41.                p1 (nth p pl)
  42.                p1 (list (car p1) (cadr p1))    
  43.         )
  44.         (repeat k
  45.             (setq    a (rand (+ pi pi))
  46.                      r (* mindist (+ 1.0 (rand 1.0)))
  47.                     p2 (polar p1 a r)
  48.                    ind (mapcar '(lambda (a) (fix (/ a cellsize))) p2)
  49.             )
  50.             (if (and (<= 0 (car p2) width) (<= 0 (cadr p2) height))    
  51.                (progn
  52.                   (setq cells (ptsaround grid ind))  
  53.            
  54.                   (if cells
  55.                      (setq tcl (tooclosep p2 cells pl))
  56.                      (setq tcl nil)
  57.                   )
  58.                   (if (not tcl)
  59.                      (progn
  60.                          (setq  i (1+ i)                  
  61.                                al (cons i al)
  62.                                 ;z (* (PerlinNoise (car p2) (cadr p2)) 10)
  63.                                pl (append pl (list (list (car p2) (cadr p2) 0.0)))  
  64.                          )                                
  65.                          (entmake (list '(0 . "POINT") '(8 . "Points") (cons 10 (list (car p2) (cadr p2) 0.0))))
  66.                          (vlax-safearray-put-element grid (car ind) (cadr ind) i)
  67.                      )
  68.                   )
  69.                )
  70.             )  
  71.         )
  72.         (setq al (vl-remove p al))
  73.            
  74.     )
  75.     pl
  76. )
  77.  
  78. (defun init2d (grid x y / i j )
  79.      (setq i -1)
  80.      (repeat x
  81.           (setq i (1+ i) j -1)
  82.           (repeat y
  83.                (setq j (1+ j))
  84.                (vlax-safearray-put-element grid i j  -1)
  85.           )
  86.      )
  87. )
  88.  
  89.  
  90. (defun ptsaround (grid ind / i j rtn tmp)
  91.  
  92.      (setq j (- (cadr ind) 2))
  93.      (repeat 5
  94.         (setq i (- (car ind) 2))
  95.         (repeat 5
  96.            (if (and (< -1 i x) (< -1 j y))
  97.               (if  (not (= (setq tmp (vlax-safearray-get-element grid i j)) -1))
  98.                  (setq rtn (cons tmp rtn))
  99.               )    
  100.            )
  101.            (setq i (1+ i))
  102.         )
  103.         (setq j (1+ j))
  104.      )
  105.      rtn
  106. )
  107.  
  108. (defun tooclosep (p cells pl / pc rtn)
  109.      
  110.      (while cells
  111.           (setq pc (nth (car cells) pl)
  112.                 cells (cdr cells)
  113.           )    
  114.           (if (< (distance pc p) mindist)
  115.              (setq rtn t cells nil)
  116.           )
  117.      )   
  118.      rtn
  119.  
  120. )
  121.  
  122.  
  123.  
  124. ;; Random number generator, Seed must remain global.    LeeMac                ;
  125. ;; Will return a real in the range 0...rng                                    ;
  126.  
  127. (defun rand (rng / x)
  128.  (* (/ (setq x 4294967296.0 seed (rem (1+ (* 1664525.0 (cond (seed) ((getvar 'DATE))))) x)) x) rng)
  129. )
  130.  
  131. ;; Floor function, Returns the largest integer not greater than x.            ;
  132. (defun floor (x) (if (minusp (rem x 1)) (- (fix x) 1) (fix x)))
  133. ;; Ceiling function, Returns the smallest integer not less than x.            ;
  134. (defun ceil  (x) (if (> (rem x 1) 0)    (+ (fix x) 1) (fix x)))
  135.  
  136.  
« Last Edit: December 10, 2013, 01:57:20 AM by ymg »

ymg

  • Guest
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #1 on: December 10, 2013, 02:04:47 AM »
Above posted has been edited to correct a bug in the ceil and floor function.

The attachment (bridson .lsp has been corrected as well.

Below a sample of the points generated, with a Voronoi Diagram overlaid.

ymg

  • Guest
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #2 on: May 04, 2015, 06:12:21 PM »
Here I've modified bridson routine to make it
a little easier on the user.

You specify a window that you want covered
with random points, and the minimum spacing
between the points.

The function returns  a list of points.

If you need to distribute item in a space
and do not want it to look aligned, this is
the ticket.

Code - Auto/Visual Lisp: [Select]
  1. ;;                                                                            ;
  2. ;; Poisson Disk Sampling per Bridson Algorithm                                ;
  3. ;;                                                                            ;
  4. ;; See: http://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf;
  5. ;;      http://devmag.org.za/2009/05/03/poisson-disk-sampling/                ;
  6. ;;                                                                            ;
  7. ;; Will return a Random Set of points with a minimum distance between them    ;
  8. ;;                                                                            ;
  9.  
  10. (defun bridson (ll ur mindist / a al cells cellsize grid i ind k p p1 p2 pl r tcl  x y)
  11.     (setq        k 30
  12.              width (- (car  ur) (car  ll))
  13.             height (- (cadr ur) (cadr ll))
  14.           cellSize (/ mindist (sqrt 2))
  15.                  x (ceil (/ width  cellsize))
  16.                  y (ceil (/ height cellsize))
  17.                 x0 (car ll)
  18.                 y0 (cadr ll)                
  19.               grid (vlax-make-safearray vlax-vbInteger (cons 0 x)(cons 0 y))
  20.                 p1 (list (rand width)(rand height))
  21.                 pl (list p1)
  22.                 al (list 0)  ; Initialize Active List with index of First Point;
  23.                ind (mapcar '(lambda (a) (fix (/ a cellsize))) p1)
  24.                  
  25.     )
  26.     (init2d grid x y)        ; Initialize the grid to all -1, then             ;
  27.                              
  28.     (vlax-safearray-put-element grid (car ind) (cadr ind) 0)
  29.      
  30.     (setq i 0) 
  31.     (while al
  32.         (setq   p (nth (fix (rand (length al))) al)
  33.                p1 (nth p pl)
  34.                p1 (list (car p1) (cadr p1))    
  35.         )
  36.         (repeat k
  37.             (setq    a (rand (+ pi pi))
  38.                      r (* mindist (+ 1.0 (rand 1.0)))
  39.                     p2 (polar p1 a r)
  40.                    ind (mapcar '(lambda (a) (fix (/ a cellsize))) p2)
  41.             )
  42.             (if (and (<= 0 (car p2) width) (<= 0 (cadr p2) height))    
  43.                (progn
  44.                   (setq cells (ptsaround grid ind))  
  45.            
  46.                   (if cells
  47.                      (setq tcl (tooclosep p2 cells pl))
  48.                      (setq tcl nil)
  49.                   )
  50.                   (if (not tcl)
  51.                      (progn
  52.                          (setq  i (1+ i)                  
  53.                                al (cons i al)
  54.                                pl (append pl (list p2))  
  55.                          )                                
  56.                          
  57.                          (vlax-safearray-put-element grid (car ind) (cadr ind) i)
  58.                      )
  59.                   )
  60.                )
  61.             )  
  62.         )
  63.         (setq al (vl-remove p al))
  64.            
  65.     )
  66.    
  67.     (mapcar '(lambda (a) (list (+ (car a) x0) (+ (cadr a) y0) 0.0)) pl)
  68. )
  69.  
  70. (defun init2d (grid x y / i j )
  71.      (setq i -1)
  72.      (repeat x
  73.           (setq i (1+ i) j -1)
  74.           (repeat y
  75.                (setq j (1+ j))
  76.                (vlax-safearray-put-element grid i j  -1)
  77.           )
  78.      )
  79. )
  80.  
  81.  
  82. (defun ptsaround (grid ind / i j rtn tmp)
  83.  
  84.      (setq j (- (cadr ind) 2))
  85.      (repeat 5
  86.         (setq i (- (car ind) 2))
  87.         (repeat 5
  88.            (if (and (< -1 i x) (< -1 j y))
  89.               (if  (not (= (setq tmp (vlax-safearray-get-element grid i j)) -1))
  90.                  (setq rtn (cons tmp rtn))
  91.               )    
  92.            )
  93.            (setq i (1+ i))
  94.         )
  95.         (setq j (1+ j))
  96.      )
  97.      rtn
  98. )
  99.  
  100. (defun tooclosep (p cells pl / pc rtn)
  101.      (while cells
  102.           (setq pc (nth (car cells) pl)
  103.                 cells (cdr cells)
  104.           )    
  105.           (if (< (distance pc p) mindist)
  106.              (setq rtn t cells nil)
  107.           )
  108.      )   
  109.      rtn
  110. )
  111. ;; Random number generator, Seed must remain global.    LeeMac                ;
  112. ;; Will return a real in the range 0...rng                                    ;
  113.  
  114. (defun rand (rng / x)
  115.  (* (/ (setq x 4294967296.0 seed (rem (1+ (* 1664525.0 (cond (seed) ((getvar 'DATE))))) x)) x) rng)
  116. )
  117.  
  118. ;; Floor function, Returns the largest integer not greater than x.            ;
  119. (defun floor (x) (if (minusp (rem x 1)) (- (fix x) 1) (fix x)))
  120. ;; Ceiling function, Returns the smallest integer not less than x.            ;
  121. (defun ceil  (x) (if (> (rem x 1) 0)    (+ (fix x) 1) (fix x)))
  122.  
  123. (defun c:test (/ ); ** p1 p2 bb md)
  124.    (setq p1 (getpoint "\nPick a Window Defining Zone: ")
  125.          p2 (getcorner p1)
  126.          pl (list p1 p2)
  127.          bb (list (apply 'mapcar (cons 'min pl)) (apply 'mapcar (cons 'max pl)))
  128.          ** (vl-cmdf "_RECTANGLE" p1 p2)
  129.          ** (entlast)
  130.          md (getdist "\nMinimum Distance Between Points: ")
  131.          pl (bridson (car bb) (cadr bb) md)
  132.    )
  133.    (mapcar '(lambda (a) (entmake (list '(0 . "POINT") '(8 . "Point") (cons 10 a)))) pl)
  134.    ;(entdel **)
  135.    (princ)
  136. )
  137.  

Here side by side diffference between:
 
    - On left  300 points sent at random in a 2700 x 2700 square.
    - On Rigth a Poisson Distribution in same square with min spacing of 150.

ymg
« Last Edit: May 04, 2015, 06:22:39 PM by ymg »

danallen

  • Guest
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #3 on: May 06, 2015, 12:06:20 AM »
interesting, thank you for posting

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #4 on: May 06, 2015, 01:28:19 AM »
Here I've modified bridson routine to make it
a little easier on the user.

< .. >

ymg


ymg,

nice job.


What did you use for the  Voronoi diagram in your sample ?

kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

ymg

  • Guest
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #5 on: May 06, 2015, 02:39:01 AM »
Kerry,

Thanks !,  I used the Triangulation program I've been working on for a while.

ymg

ribarm

  • Gator
  • Posts: 3269
  • Marko Ribar, architect
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #6 on: May 06, 2015, 09:20:42 AM »
ymg would probably code it better, but according to his 2D distribution, I revised it for 3D (if wanted to emulate points distribution for terrain modeling, points should be 3D, only in rare cases terrain is flat...) Maybe it's not what should it be, but I am satisfied and if I can save someone's typing just a little I'll be pleased too...

Code - Auto/Visual Lisp: [Select]
  1. ;;                                                                            ;
  2. ;; Poisson Disk Sampling per Bridson Algorithm                                ;
  3. ;;                                                                            ;
  4. ;; See: http://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf;
  5. ;;      http://devmag.org.za/2009/05/03/poisson-disk-sampling/                ;
  6. ;;                                                                            ;
  7. ;; Will return a Random Set of points with a minimum distance between them    ;
  8. ;;                                                                            ;
  9.  
  10. (defun bridson (ll    ur    mindist    zz /     a     al    cells cellsize
  11.                 grid  i     ind   k     p     p1    p2    pl    r
  12.                 tcl   x     y
  13.                )
  14.   (setq k        50
  15.         width    (- (car ur) (car ll))
  16.         height   (- (cadr ur) (cadr ll))
  17.         cellSize (/ mindist (sqrt 2))
  18.         x        (ceil (/ width cellsize))
  19.         y        (ceil (/ height cellsize))
  20.         x0       (car ll)
  21.         y0       (cadr ll)
  22.         z0       0.0
  23.         grid     (vlax-make-safearray vlax-vbInteger (cons 0 x) (cons 0 y))
  24.         p1       (list x0 y0 z0)
  25.         pl       (list p1)
  26.         al       (list 0)               ; Initialize Active List with index of First Point;
  27.         ind      (mapcar '(lambda (a) (fix (/ a cellsize))) p1)
  28.  
  29.   )
  30.   (init2d grid x y)                      ; Initialize the grid to all -1, then             ;
  31.  
  32.   (vlax-safearray-put-element grid (car ind) (cadr ind) 0)
  33.  
  34.   (setq i 0)
  35.   (while al
  36.     (setq p  (nth (fix (rand (length al))) al)
  37.           p1 (nth p pl)
  38.           p1 (list (car p1) (cadr p1) (caddr p1))
  39.     )
  40.     (repeat k
  41.       (setq a   (rand (+ pi pi))
  42.             r   mindist
  43.             p2  (mapcar
  44.                   '+
  45.                   (polar (list (car p1) (cadr p1) 0.0) a r)
  46.                   (list 0.0
  47.                         0.0
  48.                         (cond ((> (+ (caddr p1) (* zz 0.25)) zz)
  49.                                (- (caddr p1) (* zz (rand 1.0) 0.25))
  50.                               )
  51.                               ((< (- (caddr p1) (* zz 0.25)) (- zz))
  52.                                (+ (caddr p1) (* zz (rand 1.0) 0.25))
  53.                               )
  54.                               ((< (* zz 0.25) (caddr p1) (* zz 0.75))
  55.                                (- (caddr p1) (* zz (rand 1.0) 0.5))
  56.                               )
  57.                               ((< (* zz -0.75) (caddr p1) (* zz -0.25))
  58.                                (+ (caddr p1) (* zz (rand 1.0) 0.5))
  59.                               )
  60.                               ((and (< (caddr p1) 0.0)
  61.                                     (< (* zz -0.25) (caddr p1) (* zz 0.25))
  62.                                )
  63.                                (+ (caddr p1) (* zz (rand 1.0) 0.75))
  64.                               )
  65.                               ((and (> (caddr p1) 0.0)
  66.                                     (< (* zz -0.25) (caddr p1) (* zz 0.25))
  67.                                )
  68.                                (- (caddr p1) (* zz (rand 1.0) 0.75))
  69.                               )
  70.                               ((= (caddr p1) 0.0)
  71.                                (* zz 0.1)
  72.                               )
  73.                         )
  74.                   )
  75.                 )
  76.             ind (mapcar '(lambda (a) (fix (/ a cellsize))) p2)
  77.       )
  78.       (if (and (<= (car ll) (car p2) (car ur)) (<= (cadr ll) (cadr p2) (cadr ur)) (<= (- zz) (caddr p2) zz))
  79.         (progn
  80.           (setq cells (ptsaround grid ind))
  81.           (if cells
  82.             (setq tcl (tooclose-toofarp p2 cells pl))
  83.             (setq tcl nil)
  84.           )
  85.           (if (not tcl)
  86.             (progn
  87.               (setq i  (1+ i)
  88.                     al (cons i al)
  89.                     pl (append pl (list p2))
  90.               )
  91.  
  92.               (vlax-safearray-put-element grid (car ind) (cadr ind) i)
  93.             )
  94.           )
  95.         )
  96.       )
  97.     )
  98.     (setq al (vl-remove p al))
  99.  
  100.   )
  101.  
  102.   (mapcar '(lambda (a) (list (+ (car a) x0) (+ (cadr a) y0) (+ (caddr a) z0)))
  103.           pl
  104.   )
  105. )
  106.  
  107. (defun init2d (grid x y / i j)
  108.   (setq i -1)
  109.   (repeat x
  110.     (setq i (1+ i)
  111.           j -1
  112.     )
  113.     (repeat y
  114.       (setq j (1+ j))
  115.       (vlax-safearray-put-element grid i j -1)
  116.     )
  117.   )
  118. )
  119.  
  120.  
  121. (defun ptsaround (grid ind / i j rtn tmp)
  122.  
  123.   (setq i (- (car ind) 2))
  124.   (repeat 5
  125.     (setq j (- (cadr ind) 2))
  126.     (repeat 5
  127.       (if (and (< -1 i x) (< -1 j y))
  128.         (if
  129.           (not (= (setq tmp (vlax-safearray-get-element grid i j)) -1)
  130.           )
  131.            (setq rtn (cons tmp rtn))
  132.         )
  133.       )
  134.       (setq j (1+ j))
  135.     )
  136.     (setq i (1+ i))
  137.   )
  138.   rtn
  139. )
  140.  
  141. (defun tooclose-toofarp (p cells pl / pc rtn)
  142.   (while cells
  143.     (setq pc    (nth (car cells) pl)
  144.           cells (cdr cells)
  145.     )
  146.     (if (or (< (distance (list (car pc) (cadr pc)) (list (car p) (cadr p))) mindist) (> (abs (- (caddr pc) (caddr p))) (* zz 0.25)))
  147.       (setq rtn t
  148.             cells nil
  149.       )
  150.     )
  151.   )
  152.   rtn
  153. )
  154. ;; Random number generator, Seed must remain global.    LeeMac                ;
  155. ;; Will return a real in the range 0...rng                                    ;
  156.  
  157. (defun rand (rng / x)
  158.   (* (/ (setq x    4294967296.0
  159.               seed (rem (1+ (* 1664525.0
  160.                                (cond (seed)
  161.                                      ((getvar 'DATE))
  162.                                )
  163.                             )
  164.                         )
  165.                         x
  166.                    )
  167.         )
  168.         x
  169.      )
  170.      rng
  171.   )
  172. )
  173.  
  174. ;; Floor function, Returns the largest integer not greater than x.            ;
  175. (defun floor (x)
  176.   (if (minusp (rem x 1))
  177.     (- (fix x) 1)
  178.     (fix x)
  179.   )
  180. )
  181. ;; Ceiling function, Returns the smallest integer not less than x.            ;
  182. (defun ceil (x)
  183.   (if (> (rem x 1) 0)
  184.     (+ (fix x) 1)
  185.     (fix x)
  186.   )
  187. )
  188.  
  189. (defun c:test (/ ** p1 p2 bb md zz)
  190.  
  191.  
  192.   (command "_.UCS" "_W")
  193.   (setq p1 (getpoint "\nPick a Window Defining Zone: ")
  194.         p2 (getcorner p1)
  195.         ** (vl-cmdf "_RECTANGLE" p1 p2)
  196.         pl (list p1 p2)
  197.         bb (list (apply 'mapcar (cons 'min pl))
  198.                  (apply 'mapcar (cons 'max pl))
  199.            )
  200.         ** (vl-cmdf "_.UCS" "_M" "_non" (car bb))
  201.         bb (mapcar '(lambda (p) (trans p 0 1)) bb)
  202.         ** (entlast)
  203.         md (getdist "\nPick or specify Minimum Distance Between Points : ")
  204.         zz (getdist "\nPick or specify Maximum Elevation above and below 0.0 : ")
  205.         pl (bridson (car bb) (cadr bb) md zz)
  206.   )
  207.   (mapcar '(lambda (a)
  208.              (entmake (list '(0 . "POINT") '(8 . "Point") (cons 10 a)))
  209.            )
  210.           (mapcar '(lambda (b) (trans b 1 0)) pl)
  211.   )
  212.                                         ;(entdel **)
  213.   (princ)
  214. )
  215.  

M.R.
« Last Edit: May 06, 2015, 07:16:56 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ronjonp

  • Needs a day job
  • Posts: 7528
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #7 on: May 06, 2015, 09:32:22 AM »
interesting, thank you for posting
X2  :)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

ymg

  • Guest
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #8 on: May 06, 2015, 10:19:57 AM »
Marko,

I agree that if you wand to do synthetic terrain you need to go 3d.

It is somewhat easy to extend the same logic to get it.  However it gets very intensive,
and at this point we are limited by how big we can make this array.

In 2D, it is still very useful if you want to distribute thing in a an area, while not having
it look all aligned and yet respecting a certain density. (Tree Planting for examples)

ymg

Quote
X2  :)

There u go! ronjomp
« Last Edit: May 06, 2015, 10:48:51 AM by ymg »

ymg

  • Guest
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #9 on: May 06, 2015, 12:49:48 PM »
Marko,

For terrain modeling, 2.5 d might be sufficient as we do with triangulation.

We are only interested in the crust.

ymg

ribarm

  • Gator
  • Posts: 3269
  • Marko Ribar, architect
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #10 on: May 06, 2015, 01:02:37 PM »
Ymg, I've changed the code from here : http://www.theswamp.org/index.php?topic=45379.msg545080#msg545080
not to be too intensive... Check it, it's different - it almost uses exact 2d algorithm...

[EDIT : I had mistake so I've updated code again...]

M.R.
« Last Edit: May 06, 2015, 05:15:32 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ymg

  • Guest
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #11 on: May 06, 2015, 06:15:40 PM »
Marko,

By going 3d you end up with a cube fully of neatly spaced points.

Means we would need a 3d triangulation to exploit it.

If we want to do terrain we have to go 2.5d, that is a good random set of
points, as provided by bridson with elevations.

Elevations can be provided by yet another Noise Function namely "Perlin Noise".

Here a small program not extensively tested to illustrate what I mean:

Code - Auto/Visual Lisp: [Select]
  1. ;;                                                                            ;
  2. ;; PerlinNoise_2d       by ymg                                                ;
  3. ;;                                                                            ;
  4. ;; Function to Generate Perlin Noise in Two Dimension                         ;
  5. ;;                                                                            ;
  6. ;; From peudo-code by Hugo Elias at:                                          ;
  7. ;;         http://freespace.virgin.net/hugo.elias/models/m_perlin.htm         ;
  8. ;;                                                                            ;
  9. ;; Notes: Variables persistence and number_of_octaves are defined in calling  ;
  10. ;;        Program, although they could be added as arguments.                 ;
  11. ;;                                                                            ;
  12.  
  13. (defun PerlinNoise_2D (x y / p n frequency amplitude total)
  14.  
  15.    (defun noise (x y / s x)
  16.       (setq s (lsh (+ x (* y 57)) -13))    
  17.       (/ (setq x 4294967296.0 s (rem (1+ (* 1664525.0 s)) x)) x)
  18.    )
  19.  
  20.    (defun smoothnoise (x y)  
  21.       (+ (/ (+ (noise (1- x) (1- y)) (noise (1+ x) (1- y)) (noise (1- x) (1+ y)) (noise (1+ x) (1+ y))) 16)
  22.          (/ (+ (noise (1- x) y)  (noise (1+ x) y) (noise x (1- y)) (noise x (1+ y))) 8)
  23.          (/ (noise x y) 4)
  24.       )
  25.    )  
  26.  
  27.    (defun interpolatenoise (x y / intx fracx v1 v2 v3 v4 i1 i2)  
  28.       (setq  intx (fix x)      inty (fix y)
  29.             fracx (- x intx)  fracy (- y inty)
  30.                v1 (smoothmoise intx inty)        
  31.                v2 (smoothmoise (1+ intx) inty)
  32.                v3 (smoothmoise intx (1+ inty))
  33.                v4 (smoothmoise (1+ intx) (1+ inty))
  34.          
  35.                i1 (interpolate v1 v2 fracx)
  36.                i2 (interpolate v3 v4 fracx)
  37.       )
  38.       (interpolate i1 i2 fracy)
  39.    )
  40.  
  41.    ;;                                                                         ;
  42.    ;; Cosine Interpolation                                                    ;
  43.    ;;                                                                         ;
  44.  
  45.    (defun interpolate (a b x)
  46.       (setq f (1- (cos (* x pi))))
  47.       (+ (* a (1- f)) (* b f))
  48.    )  
  49.        
  50.  
  51.    ;;                                                                         ;
  52.    ;; in_range      by ElpanovEvgeniy       (recursive)                       ;
  53.    ;;                                                                         ;
  54.    ;; Similar to the Python Function                                          ;
  55.    ;;                                                                         ;
  56.  
  57.    (defun in_range (s e i)
  58.       (if (or (and (> i 0) (< s e)) (and (< i 0) (> s e)))
  59.          (cons s (in_range (+ i s) e i))
  60.       )
  61.    )
  62.  
  63.    ;;                                                                         ;
  64.    ;; Body of Function PerlinNoise                                            ;
  65.    ;;                                                                         ;
  66.  
  67.    (setq total 0
  68.            p persistence
  69.            n (1- number_of_octaves)
  70.    )
  71.    (foreach i (in_range 0 n 1)
  72.       (setq frequency (expt 2 i)
  73.             amplitude (expt p i)
  74.             total (+ total (* (interpolatenoise (* x frequency) (* y frequency)) amplitude))
  75.       )
  76.    )  
  77.    total
  78. )
  79.  
  80.  
  81. ;;                                                                            ;
  82. ;; Poisson Disk Sampling per Bridson Algorithm                                ;
  83. ;;                                                                            ;
  84. ;; See: http://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf;
  85. ;;      http://devmag.org.za/2009/05/03/poisson-disk-sampling/                ;
  86. ;;                                                                            ;
  87. ;; Will return a Random Set of points with a minimum distance between them    ;
  88. ;;                                                                            ;
  89.  
  90. (defun bridson (ll ur mindist / a al cells cellsize grid i ind k p p1 p2 pl r tcl  x y)
  91.     (setq        k 30
  92.              width (- (car  ur) (car  ll))
  93.             height (- (cadr ur) (cadr ll))
  94.           cellSize (/ mindist (sqrt 2))
  95.                  x (ceil (/ width  cellsize))
  96.                  y (ceil (/ height cellsize))
  97.                 x0 (car ll)
  98.                 y0 (cadr ll)                
  99.               grid (vlax-make-safearray vlax-vbInteger (cons 0 x)(cons 0 y))
  100.                 p1 (list (rand width)(rand height))
  101.                 pl (list p1)
  102.                 al (list 0)  ; Initialize Active List with index of First Point;
  103.                ind (mapcar '(lambda (a) (fix (/ a cellsize))) p1)
  104.                  
  105.     )
  106.     (init2d grid x y)        ; Initialize the grid to all -1, then             ;
  107.                              
  108.     (vlax-safearray-put-element grid (car ind) (cadr ind) 0)
  109.      
  110.     (setq i 0) 
  111.     (while al
  112.         (setq   p (nth (fix (rand (length al))) al)
  113.                p1 (nth p pl)
  114.                p1 (list (car p1) (cadr p1))    
  115.         )
  116.         (repeat k
  117.             (setq    a (rand (+ pi pi))
  118.                      r (* mindist (+ 1.0 (rand 1.0)))
  119.                     p2 (polar p1 a r)
  120.                    ind (mapcar '(lambda (a) (fix (/ a cellsize))) p2)
  121.             )
  122.             (if (and (<= 0 (car p2) width) (<= 0 (cadr p2) height))    
  123.                (progn
  124.                   (setq cells (ptsaround grid ind))  
  125.            
  126.                   (if cells
  127.                      (setq tcl (tooclosep p2 cells pl))
  128.                      (setq tcl nil)
  129.                   )
  130.                   (if (not tcl)
  131.                      (progn
  132.                          (setq  i (1+ i)                  
  133.                                al (cons i al)
  134.                                pl (append pl (list p2))  
  135.                          )                                
  136.                          
  137.                          (vlax-safearray-put-element grid (car ind) (cadr ind) i)
  138.                      )
  139.                   )
  140.                )
  141.             )  
  142.         )
  143.         (setq al (vl-remove p al))
  144.            
  145.     )
  146.    
  147.     (mapcar '(lambda (a) (list (+ (car a) x0) (+ (cadr a) y0) 0.0)) pl)
  148. )
  149.  
  150. (defun init2d (grid x y / i j )
  151.      (setq i -1)
  152.      (repeat x
  153.           (setq i (1+ i) j -1)
  154.           (repeat y
  155.                (setq j (1+ j))
  156.                (vlax-safearray-put-element grid i j  -1)
  157.           )
  158.      )
  159. )
  160.  
  161.  
  162. (defun ptsaround (grid ind / i j rtn tmp)
  163.  
  164.      (setq j (- (cadr ind) 2))
  165.      (repeat 5
  166.         (setq i (- (car ind) 2))
  167.         (repeat 5
  168.            (if (and (< -1 i x) (< -1 j y))
  169.               (if  (not (= (setq tmp (vlax-safearray-get-element grid i j)) -1))
  170.                  (setq rtn (cons tmp rtn))
  171.               )    
  172.            )
  173.            (setq i (1+ i))
  174.         )
  175.         (setq j (1+ j))
  176.      )
  177.      rtn
  178. )
  179.  
  180. (defun tooclosep (p cells pl / pc rtn)
  181.      (while cells
  182.           (setq pc (nth (car cells) pl)
  183.                 cells (cdr cells)
  184.           )    
  185.           (if (< (distance pc p) mindist)
  186.              (setq rtn t cells nil)
  187.           )
  188.      )   
  189.      rtn
  190. )
  191.  
  192.  
  193.  
  194. ;; Random number generator, Seed must remain global.    LeeMac                ;
  195. ;; Will return a real in the range 0...rng                                    ;
  196.  
  197. (defun rand (rng / x)
  198.  (* (/ (setq x 4294967296.0 seed (rem (1+ (* 1664525.0 (cond (seed) ((getvar 'DATE))))) x)) x) rng)
  199. )
  200.  
  201. ;; Floor function, Returns the largest integer not greater than x.            ;
  202. (defun floor (x) (if (minusp (rem x 1)) (- (fix x) 1) (fix x)))
  203. ;; Ceiling function, Returns the smallest integer not less than x.            ;
  204. (defun ceil  (x) (if (> (rem x 1) 0)    (+ (fix x) 1) (fix x)))
  205.  
  206.  
  207.  
  208.  
  209. (defun c:gen_terrain (/  ** p1 p2 bb md)
  210.  
  211.    (setq persistence 0.25
  212.          number_of_octaves 6
  213.          vexag 10
  214.    )
  215.  
  216.  
  217.    (setq p1 (getpoint "\nPick a Window Defining Zone: ")
  218.          p2 (getcorner p1)
  219.          pl (list p1 p2)
  220.          bb (list (apply 'mapcar (cons 'min pl)) (apply 'mapcar (cons 'max pl)))
  221.          ** (vl-cmdf "_RECTANGLE" p1 p2)
  222.          ** (entlast)
  223.          md (getdist "\nMinimum Distance Between Points: ")
  224.          pl (bridson (car bb) (cadr bb) md)
  225.    )
  226.  
  227.    ;; Applying Perlin Noise to our Point List to Get Z Values                 ;
  228.    (setq pl (mapcar '(lambda (a) (list (car a) (cadr a) (* (PerlinNoise_2D (car a) (cadr a)) vexag))) pl))
  229.          
  230.    ;; Drawing our Point List to the Screen                                    ;
  231.    (mapcar '(lambda (a) (entmakex (list '(0 . "POINT") '(8 . "Point") (cons 10 a)))) pl)
  232.    (entdel **)  ; If you want to delete the rectangle after selection.       ;
  233.    (princ)
  234. )
  235.  

We could use the same "Perlin Noise" function to generate a random contour instead of
a rectangle.

But essentially this is the technique they use in Game Software to generate terrain.
There is of course more details to attend, like coloring or texturing as a function of
heigth etc.

Heres a crude one generated with persistance set at 0.25 and no_of_octave 6.
I did not loft it down to zero.  There could be bugs lurking in there as I did not
test it extensively.

More details on Hugo Elias'es page :  http://freespace.virgin.net/hugo.elias/models/m_perlin.htm

ymg

« Last Edit: May 06, 2015, 06:41:19 PM by ymg »

ribarm

  • Gator
  • Posts: 3269
  • Marko Ribar, architect
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #12 on: May 06, 2015, 06:28:00 PM »
Thanks ymg, I was constantly updating my post... Hope it now fits the most for small waving of terrain...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ymg

  • Guest
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #13 on: May 06, 2015, 06:37:59 PM »
Marko,

Another good source of info on the subject of terrain generating
and games here: http://theory.stanford.edu/~amitp/GameProgramming/

ymg

qjchen

  • Bull Frog
  • Posts: 285
  • Best wishes to all
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #14 on: May 06, 2015, 08:22:51 PM »
Thank you ymg for your sharing.

I think it would be useful in finite element mesh.

thx~
http://qjchen.mjtd.com
My blog http://chenqj.blogspot.com (Chinese, can be translate into English)

ymg

  • Guest
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #15 on: May 07, 2015, 03:42:13 AM »
qjchen,

Thanks, I am not too familiar with finite element but it could be.

Sampling function and Noise functions are extensively used in
Texture generation and Graphic Filters (Photoshop).

ymg

ribarm

  • Gator
  • Posts: 3269
  • Marko Ribar, architect
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #16 on: May 07, 2015, 04:45:53 AM »
Anyway it seems that the best thing to overcome this intensive waving is actually to code it for waving... Here is my wave version, but put 1 or 2 waves when asked...

Code - Auto/Visual Lisp: [Select]
  1. ;;                                                                            ;
  2. ;; Poisson Disk Sampling per Bridson Algorithm                                ;
  3. ;;                                                                            ;
  4. ;; See: http://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf;
  5. ;;      http://devmag.org.za/2009/05/03/poisson-disk-sampling/                ;
  6. ;;                                                                            ;
  7. ;; Will return a Random Set of points with a minimum distance between them    ;
  8. ;;                                                                            ;
  9.  
  10. (defun bridson (ll    ur    mindist     /     a     al    cells cellsize
  11.                 grid  i     ind   k     p     p1    p2    pl    r
  12.                 tcl   x     y
  13.                )
  14.   (setq k        30
  15.         width    (- (car ur) (car ll))
  16.         height   (- (cadr ur) (cadr ll))
  17.         cellSize (/ mindist (sqrt 2))
  18.         x        (ceil (/ width cellsize))
  19.         y        (ceil (/ height cellsize))
  20.         x0       (car ll)
  21.         y0       (cadr ll)
  22.         grid     (vlax-make-safearray vlax-vbInteger (cons 0 x) (cons 0 y))
  23.         p1       (list (rand width) (rand height))
  24.         pl       (list p1)
  25.         al       (list 0)               ; Initialize Active List with index of First Point;
  26.         ind      (mapcar '(lambda (a) (fix (/ a cellsize))) p1)
  27.  
  28.   )
  29.   (init2d grid x y)                     ; Initialize the grid to all -1, then             ;
  30.  
  31.   (vlax-safearray-put-element grid (car ind) (cadr ind) 0)
  32.  
  33.   (setq i 0)
  34.   (while al
  35.     (setq p  (nth (fix (rand (length al))) al)
  36.           p1 (nth p pl)
  37.           p1 (list (car p1) (cadr p1))
  38.     )
  39.     (repeat k
  40.       (setq a   (rand (+ pi pi))
  41.             r   (* mindist (+ 1.0 (rand 1.0)))
  42.             p2  (polar p1 a r)
  43.             ind (mapcar '(lambda (a) (fix (/ a cellsize))) p2)
  44.       )
  45.       (if (and (<= 0 (car p2) width) (<= 0 (cadr p2) height))
  46.         (progn
  47.           (setq cells (ptsaround grid ind))
  48.           (if cells
  49.             (setq tcl (tooclosep p2 cells pl))
  50.             (setq tcl nil)
  51.           )
  52.           (if (not tcl)
  53.             (progn
  54.               (setq i  (1+ i)
  55.                     al (cons i al)
  56.                     pl (append pl (list p2))
  57.               )
  58.  
  59.               (vlax-safearray-put-element grid (car ind) (cadr ind) i)
  60.             )
  61.           )
  62.         )
  63.       )
  64.     )
  65.     (setq al (vl-remove p al))
  66.  
  67.   )
  68.  
  69.   (mapcar '(lambda (a) (list (+ (car a) x0) (+ (cadr a) y0) 0.0))
  70.           pl
  71.   )
  72. )
  73.  
  74. (defun init2d (grid x y / i j)
  75.   (setq i -1)
  76.   (repeat x
  77.     (setq i (1+ i)
  78.           j -1
  79.     )
  80.     (repeat y
  81.       (setq j (1+ j))
  82.       (vlax-safearray-put-element grid i j -1)
  83.     )
  84.   )
  85. )
  86.  
  87.  
  88. (defun ptsaround (grid ind / i j rtn tmp)
  89.  
  90.   (setq j (- (cadr ind) 2))
  91.   (repeat 5
  92.     (setq i (- (car ind) 2))
  93.     (repeat 5
  94.       (if (and (< -1 i x) (< -1 j y))
  95.         (if
  96.           (not (= (setq tmp (vlax-safearray-get-element grid i j)) -1)
  97.           )
  98.            (setq rtn (cons tmp rtn))
  99.         )
  100.       )
  101.       (setq i (1+ i))
  102.     )
  103.     (setq j (1+ j))
  104.   )
  105.   rtn
  106. )
  107.  
  108. (defun tooclosep (p cells pl / pc rtn)
  109.   (while cells
  110.     (setq pc    (nth (car cells) pl)
  111.           cells (cdr cells)
  112.     )
  113.     (if (< (distance pc p) mindist)
  114.       (setq rtn t
  115.             cells nil
  116.       )
  117.     )
  118.   )
  119.   rtn
  120. )
  121. ;; Random number generator, Seed must remain global.    LeeMac                ;
  122. ;; Will return a real in the range 0...rng                                    ;
  123.  
  124. (defun rand (rng / x)
  125.   (* (/ (setq x    4294967296.0
  126.               seed (rem (1+ (* 1664525.0
  127.                                (cond (seed)
  128.                                      ((getvar 'DATE))
  129.                                )
  130.                             )
  131.                         )
  132.                         x
  133.                    )
  134.         )
  135.         x
  136.      )
  137.      rng
  138.   )
  139. )
  140.  
  141. ;; Floor function, Returns the largest integer not greater than x.            ;
  142. (defun floor (x)
  143.   (if (minusp (rem x 1))
  144.     (- (fix x) 1)
  145.     (fix x)
  146.   )
  147. )
  148. ;; Ceiling function, Returns the smallest integer not less than x.            ;
  149. (defun ceil (x)
  150.   (if (> (rem x 1) 0)
  151.     (+ (fix x) 1)
  152.     (fix x)
  153.   )
  154. )
  155.  
  156. (defun c:test (/ ** p1 p2 bb md zz nw dw kk jj ii z zi zl i dl dr dlst j k e pl pll)
  157.  
  158.  
  159.   (command "_.UCS" "_W")
  160.   (setq p1 (getpoint "\nPick a Window Defining Zone: ")
  161.         p2 (getcorner p1)
  162.         ** (vl-cmdf "_.RECTANGLE" "_non" p1 "_non" p2)
  163.         pl (list p1 p2)
  164.         bb (list (apply 'mapcar (cons 'min pl))
  165.                  (apply 'mapcar (cons 'max pl))
  166.            )
  167.         ** (vl-cmdf "_.UCS" "_M" "_non" (car bb))
  168.         bb (mapcar '(lambda (p) (trans p 0 1)) bb)
  169.         md (getdist
  170.              "\nPick or specify Minimum Distance Between Points : "
  171.            )
  172.         zz (getdist
  173.              "\nPick or specify Maximum Elevation above and below 0.0 : "
  174.            )
  175.         ** (initget 7)
  176.         nw (getint
  177.              "\nSpecify number of waves along X axis : "
  178.            )
  179.         ** (entlast)
  180.         pl (bridson (car bb) (cadr bb) md)
  181.         pl (vl-sort pl '(lambda (a b) (< (car a) (car b))))
  182.         kk -1
  183.   )
  184.  
  185.   (repeat nw
  186.     (setq jj 0)
  187.     (setq kk (1+ kk))
  188.     (repeat 16
  189.       (setq jj (1+ jj))
  190.       (setq ii (+ (* kk 16) jj))
  191.       (cond
  192.         ((= jj 1)
  193.          (repeat 5
  194.            (setq z (* zz (rand 1.0) 0.25))
  195.            (setq zi (cons ii z))
  196.            (setq zl (cons zi zl))
  197.          )
  198.         )
  199.         ((= jj 2)
  200.          (repeat 5
  201.            (setq z (+ (* zz 0.25) (* zz (rand 1.0) 0.25)))
  202.            (setq zi (cons ii z))
  203.            (setq zl (cons zi zl))
  204.          )
  205.         )
  206.         ((= jj 3)
  207.          (repeat 5
  208.            (setq z (+ (* zz 0.5) (* zz (rand 1.0) 0.25)))
  209.            (setq zi (cons ii z))
  210.            (setq zl (cons zi zl))
  211.          )
  212.         )
  213.         ((= jj 4)
  214.          (repeat 5
  215.            (setq z (+ (* zz 0.75) (* zz (rand 1.0) 0.25)))
  216.            (setq zi (cons ii z))
  217.            (setq zl (cons zi zl))
  218.          )
  219.         )
  220.         ((= jj 5)
  221.          (repeat 5
  222.            (setq z (+ (* zz 0.75) (* zz (rand 1.0) 0.25)))
  223.            (setq zi (cons ii z))
  224.            (setq zl (cons zi zl))
  225.          )
  226.         )
  227.         ((= jj 6)
  228.          (repeat 5
  229.            (setq z (+ (* zz 0.5) (* zz (rand 1.0) 0.25)))
  230.            (setq zi (cons ii z))
  231.            (setq zl (cons zi zl))
  232.          )
  233.         )
  234.         ((= jj 7)
  235.          (repeat 5
  236.            (setq z (+ (* zz 0.25) (* zz (rand 1.0) 0.25)))
  237.            (setq zi (cons ii z))
  238.            (setq zl (cons zi zl))
  239.          )
  240.         )
  241.         ((= jj 8)
  242.          (repeat 5
  243.            (setq z (* zz (rand 1.0) 0.25))
  244.            (setq zi (cons ii z))
  245.            (setq zl (cons zi zl))
  246.          )
  247.         )
  248.         ((= jj 9)
  249.          (repeat 5
  250.            (setq z (* (- zz) (rand 1.0) 0.25))
  251.            (setq zi (cons ii z))
  252.            (setq zl (cons zi zl))
  253.          )
  254.         )
  255.         ((= jj 10)
  256.          (repeat 5
  257.            (setq z (+ (* (- zz) 0.25) (* (- zz) (rand 1.0) 0.25)))
  258.            (setq zi (cons ii z))
  259.            (setq zl (cons zi zl))
  260.          )
  261.         )
  262.         ((= jj 11)
  263.          (repeat 5
  264.            (setq z (+ (* (- zz) 0.5) (* (- zz) (rand 1.0) 0.25)))
  265.            (setq zi (cons ii z))
  266.            (setq zl (cons zi zl))
  267.          )
  268.         )
  269.         ((= jj 12)
  270.          (repeat 5
  271.            (setq z (+ (* (- zz) 0.75) (* (- zz) (rand 1.0) 0.25)))
  272.            (setq zi (cons ii z))
  273.            (setq zl (cons zi zl))
  274.          )
  275.         )
  276.         ((= jj 13)
  277.          (repeat 5
  278.            (setq z (+ (* (- zz) 0.75) (* (- zz) (rand 1.0) 0.25)))
  279.            (setq zi (cons ii z))
  280.            (setq zl (cons zi zl))
  281.          )
  282.         )
  283.         ((= jj 14)
  284.          (repeat 5
  285.            (setq z (+ (* (- zz) 0.5) (* (- zz) (rand 1.0) 0.25)))
  286.            (setq zi (cons ii z))
  287.            (setq zl (cons zi zl))
  288.          )
  289.         )
  290.         ((= jj 15)
  291.          (repeat 5
  292.            (setq z (+ (* (- zz) 0.25) (* (- zz) (rand 1.0) 0.25)))
  293.            (setq zi (cons ii z))
  294.            (setq zl (cons zi zl))
  295.          )
  296.         )
  297.         ((= jj 16)
  298.          (repeat 5
  299.            (setq z (* (- zz) (rand 1.0) 0.25))
  300.            (setq zi (cons ii z))
  301.            (setq zl (cons zi zl))
  302.          )
  303.         )
  304.       )
  305.     )
  306.   )
  307.  
  308.   (setq dw (/ (caadr bb) ii))
  309.   (setq i 0)
  310.   (repeat ii
  311.     (setq i (1+ i))
  312.     (setq dl (* (1- i) dw)
  313.           dr (* i dw)
  314.     )
  315.     (setq dlst (cons (cons i (list dl dr)) dlst))
  316.   )
  317.   (setq dlst (reverse dlst))
  318.   (foreach p pl
  319.     (setq j (vl-some '(lambda ( x ) (if (< (cadr x) (car p) (caddr x)) (car x))) dlst))
  320.     (setq k (acet-list-m-assoc j zl))
  321.     (setq e (cdr (nth (fix (rand (length k))) k)))
  322.     (setq p (list (car p) (cadr p) e))
  323.     (setq pll (cons p pll))
  324.   )
  325.  
  326.   (setq pll (reverse pll))
  327.  
  328.   (mapcar '(lambda (a)
  329.              (entmake (list '(0 . "POINT") '(8 . "Point") (cons 10 a)))
  330.            )
  331.           (mapcar '(lambda (b) (trans b 1 0)) pll)
  332.   )
  333.                                         ;(entdel **)
  334.   (princ)
  335. )
  336.  

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

:)

M.R. on Youtube

ymg

  • Guest
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #17 on: May 07, 2015, 07:01:01 AM »
Marko,

Nice !!!, here generated with your wave proggie.

Possibilities are endless.

ymg

« Last Edit: May 07, 2015, 07:04:21 AM by ymg »

ribarm

  • Gator
  • Posts: 3269
  • Marko Ribar, architect
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #18 on: May 07, 2015, 07:52:34 AM »
Now that I've posted linear X axis version, here is radial one based on the same algorithm... File is little larger, so I'll attach it...

M.R.
« Last Edit: May 07, 2015, 08:39:19 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ymg

  • Guest
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #19 on: May 07, 2015, 04:26:57 PM »
Marko,

I didn't have a chance yet to test your radial wave but I will.

I was on the Net researching some more on "Perlin Noise"
and I stumbled on this to generate a landscape on a sphere.

I know you like to work with them sphere, so have a look
here:   http://freespace.virgin.net/hugo.elias/models/m_landsp.htm

It is again by the same guy Hugo Elias.


ymg


ribarm

  • Gator
  • Posts: 3269
  • Marko Ribar, architect
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #20 on: May 08, 2015, 11:00:48 AM »
I don't know ab spheres, but for a mathematical functions projected on elevations, combination of RND planar distribution and elevations obtained by points 2D data for waves is certainly possible by sinus function... So no need to double RND algorthim - it can be used just for poison 2D distribution... I am curious how no one haven't posted remark ab this... And codes are smaller than I've imagined...

For X axis waving...
Code - Auto/Visual Lisp: [Select]
  1. ;;                                                                            ;
  2. ;; Poisson Disk Sampling per Bridson Algorithm                                ;
  3. ;;                                                                            ;
  4. ;; See: http://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf;
  5. ;;      http://devmag.org.za/2009/05/03/poisson-disk-sampling/                ;
  6. ;;                                                                            ;
  7. ;; Will return a Random Set of points with a minimum distance between them    ;
  8. ;;                                                                            ;
  9.  
  10. (defun bridson (ll    ur    mindist     /     a     al    cells cellsize
  11.                 grid  i     ind   k     p     p1    p2    pl    r
  12.                 tcl   x     y
  13.                )
  14.   (setq k        30
  15.         width    (- (car ur) (car ll))
  16.         height   (- (cadr ur) (cadr ll))
  17.         cellSize (/ mindist (sqrt 2))
  18.         x        (ceil (/ width cellsize))
  19.         y        (ceil (/ height cellsize))
  20.         x0       (car ll)
  21.         y0       (cadr ll)
  22.         grid     (vlax-make-safearray vlax-vbInteger (cons 0 x) (cons 0 y))
  23.         p1       (list (rand width) (rand height))
  24.         pl       (list p1)
  25.         al       (list 0)               ; Initialize Active List with index of First Point;
  26.         ind      (mapcar '(lambda (a) (fix (/ a cellsize))) p1)
  27.  
  28.   )
  29.   (init2d grid x y)                     ; Initialize the grid to all -1, then             ;
  30.  
  31.   (vlax-safearray-put-element grid (car ind) (cadr ind) 0)
  32.  
  33.   (setq i 0)
  34.   (while al
  35.     (setq p  (nth (fix (rand (length al))) al)
  36.           p1 (nth p pl)
  37.           p1 (list (car p1) (cadr p1))
  38.     )
  39.     (repeat k
  40.       (setq a   (rand (+ pi pi))
  41.             r   (* mindist (+ 1.0 (rand 1.0)))
  42.             p2  (polar p1 a r)
  43.             ind (mapcar '(lambda (a) (fix (/ a cellsize))) p2)
  44.       )
  45.       (if (and (<= 0 (car p2) width) (<= 0 (cadr p2) height))
  46.         (progn
  47.           (setq cells (ptsaround grid ind))
  48.           (if cells
  49.             (setq tcl (tooclosep p2 cells pl))
  50.             (setq tcl nil)
  51.           )
  52.           (if (not tcl)
  53.             (progn
  54.               (setq i  (1+ i)
  55.                     al (cons i al)
  56.                     pl (append pl (list p2))
  57.               )
  58.  
  59.               (vlax-safearray-put-element grid (car ind) (cadr ind) i)
  60.             )
  61.           )
  62.         )
  63.       )
  64.     )
  65.     (setq al (vl-remove p al))
  66.  
  67.   )
  68.  
  69.   (mapcar '(lambda (a) (list (+ (car a) x0) (+ (cadr a) y0) 0.0))
  70.           pl
  71.   )
  72. )
  73.  
  74. (defun init2d (grid x y / i j)
  75.   (setq i -1)
  76.   (repeat x
  77.     (setq i (1+ i)
  78.           j -1
  79.     )
  80.     (repeat y
  81.       (setq j (1+ j))
  82.       (vlax-safearray-put-element grid i j -1)
  83.     )
  84.   )
  85. )
  86.  
  87.  
  88. (defun ptsaround (grid ind / i j rtn tmp)
  89.  
  90.   (setq j (- (cadr ind) 2))
  91.   (repeat 5
  92.     (setq i (- (car ind) 2))
  93.     (repeat 5
  94.       (if (and (< -1 i x) (< -1 j y))
  95.         (if
  96.           (not (= (setq tmp (vlax-safearray-get-element grid i j)) -1)
  97.           )
  98.            (setq rtn (cons tmp rtn))
  99.         )
  100.       )
  101.       (setq i (1+ i))
  102.     )
  103.     (setq j (1+ j))
  104.   )
  105.   rtn
  106. )
  107.  
  108. (defun tooclosep (p cells pl / pc rtn)
  109.   (while cells
  110.     (setq pc    (nth (car cells) pl)
  111.           cells (cdr cells)
  112.     )
  113.     (if (< (distance pc p) mindist)
  114.       (setq rtn t
  115.             cells nil
  116.       )
  117.     )
  118.   )
  119.   rtn
  120. )
  121. ;; Random number generator, Seed must remain global.    LeeMac                ;
  122. ;; Will return a real in the range 0...rng                                    ;
  123.  
  124. (defun rand (rng / x)
  125.   (* (/ (setq x    4294967296.0
  126.               seed (rem (1+ (* 1664525.0
  127.                                (cond (seed)
  128.                                      ((getvar 'DATE))
  129.                                )
  130.                             )
  131.                         )
  132.                         x
  133.                    )
  134.         )
  135.         x
  136.      )
  137.      rng
  138.   )
  139. )
  140.  
  141. ;; Floor function, Returns the largest integer not greater than x.            ;
  142. (defun floor (x)
  143.   (if (minusp (rem x 1))
  144.     (- (fix x) 1)
  145.     (fix x)
  146.   )
  147. )
  148. ;; Ceiling function, Returns the smallest integer not less than x.            ;
  149. (defun ceil (x)
  150.   (if (> (rem x 1) 0)
  151.     (+ (fix x) 1)
  152.     (fix x)
  153.   )
  154. )
  155.  
  156. (defun c:test (/ ** p1 p2 bb md zz nw dw e pl pll)
  157.  
  158.  
  159.   (command "_.UCS" "_W")
  160.   (setq p1 (getpoint "\nPick a Window Defining Zone: ")
  161.         p2 (getcorner p1)
  162.         ** (vl-cmdf "_.RECTANGLE" "_non" p1 "_non" p2)
  163.         pl (list p1 p2)
  164.         bb (list (apply 'mapcar (cons 'min pl))
  165.                  (apply 'mapcar (cons 'max pl))
  166.            )
  167.         ** (vl-cmdf "_.UCS" "_M" "_non" (car bb))
  168.         bb (mapcar '(lambda (p) (trans p 0 1)) bb)
  169.         md (getdist
  170.              "\nPick or specify Minimum Distance Between Points : "
  171.            )
  172.         zz (getdist
  173.              "\nPick or specify Maximum Elevation above and below 0.0 : "
  174.            )
  175.         ** (initget 7)
  176.         nw (getint
  177.              "\nSpecify number of waves along X axis : "
  178.            )
  179.         ** (entlast)
  180.         pl (bridson (car bb) (cadr bb) md)
  181.         pl (vl-sort pl '(lambda (a b) (< (car a) (car b))))
  182.   )
  183.  
  184.   (setq dw (/ (caadr bb) nw))
  185.   (foreach p pl
  186.     (setq e (* zz (sin (* (/ (rem (car p) dw) dw) 2.0 pi))))
  187.     (setq p (list (car p) (cadr p) e))
  188.     (setq pll (cons p pll))
  189.   )
  190.  
  191.   (setq pll (reverse pll))
  192.  
  193.   (mapcar '(lambda (a)
  194.              (entmake (list '(0 . "POINT") '(8 . "Point") (cons 10 a)))
  195.            )
  196.           (mapcar '(lambda (b) (trans b 1 0)) pll)
  197.   )
  198.                                         ;(entdel **)
  199.   (princ)
  200. )
  201.  

For radial waving...
Code - Auto/Visual Lisp: [Select]
  1. ;;                                                                            ;
  2. ;; Poisson Disk Sampling per Bridson Algorithm                                ;
  3. ;;                                                                            ;
  4. ;; See: http://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf;
  5. ;;      http://devmag.org.za/2009/05/03/poisson-disk-sampling/                ;
  6. ;;                                                                            ;
  7. ;; Will return a Random Set of points with a minimum distance between them    ;
  8. ;;                                                                            ;
  9.  
  10. (defun bridson (ll    ur    mindist     /     a     al    cells cellsize
  11.                 grid  i     ind   k     p     p1    p2    pl    r
  12.                 tcl   x     y
  13.                )
  14.   (setq k        30
  15.         width    (- (car ur) (car ll))
  16.         height   (- (cadr ur) (cadr ll))
  17.         cellSize (/ mindist (sqrt 2))
  18.         x        (ceil (/ width cellsize))
  19.         y        (ceil (/ height cellsize))
  20.         x0       (car ll)
  21.         y0       (cadr ll)
  22.         grid     (vlax-make-safearray vlax-vbInteger (cons 0 x) (cons 0 y))
  23.         p1       (list (rand width) (rand height))
  24.         pl       (list p1)
  25.         al       (list 0)               ; Initialize Active List with index of First Point;
  26.         ind      (mapcar '(lambda (a) (fix (/ a cellsize))) p1)
  27.  
  28.   )
  29.   (init2d grid x y)                     ; Initialize the grid to all -1, then             ;
  30.  
  31.   (vlax-safearray-put-element grid (car ind) (cadr ind) 0)
  32.  
  33.   (setq i 0)
  34.   (while al
  35.     (setq p  (nth (fix (rand (length al))) al)
  36.           p1 (nth p pl)
  37.           p1 (list (car p1) (cadr p1))
  38.     )
  39.     (repeat k
  40.       (setq a   (rand (+ pi pi))
  41.             r   (* mindist (+ 1.0 (rand 1.0)))
  42.             p2  (polar p1 a r)
  43.             ind (mapcar '(lambda (a) (fix (/ a cellsize))) p2)
  44.       )
  45.       (if (and (<= 0 (car p2) width) (<= 0 (cadr p2) height))
  46.         (progn
  47.           (setq cells (ptsaround grid ind))
  48.           (if cells
  49.             (setq tcl (tooclosep p2 cells pl))
  50.             (setq tcl nil)
  51.           )
  52.           (if (not tcl)
  53.             (progn
  54.               (setq i  (1+ i)
  55.                     al (cons i al)
  56.                     pl (append pl (list p2))
  57.               )
  58.  
  59.               (vlax-safearray-put-element grid (car ind) (cadr ind) i)
  60.             )
  61.           )
  62.         )
  63.       )
  64.     )
  65.     (setq al (vl-remove p al))
  66.  
  67.   )
  68.  
  69.   (mapcar '(lambda (a) (list (+ (car a) x0) (+ (cadr a) y0) 0.0))
  70.           pl
  71.   )
  72. )
  73.  
  74. (defun init2d (grid x y / i j)
  75.   (setq i -1)
  76.   (repeat x
  77.     (setq i (1+ i)
  78.           j -1
  79.     )
  80.     (repeat y
  81.       (setq j (1+ j))
  82.       (vlax-safearray-put-element grid i j -1)
  83.     )
  84.   )
  85. )
  86.  
  87.  
  88. (defun ptsaround (grid ind / i j rtn tmp)
  89.  
  90.   (setq j (- (cadr ind) 2))
  91.   (repeat 5
  92.     (setq i (- (car ind) 2))
  93.     (repeat 5
  94.       (if (and (< -1 i x) (< -1 j y))
  95.         (if
  96.           (not (= (setq tmp (vlax-safearray-get-element grid i j)) -1)
  97.           )
  98.            (setq rtn (cons tmp rtn))
  99.         )
  100.       )
  101.       (setq i (1+ i))
  102.     )
  103.     (setq j (1+ j))
  104.   )
  105.   rtn
  106. )
  107.  
  108. (defun tooclosep (p cells pl / pc rtn)
  109.   (while cells
  110.     (setq pc    (nth (car cells) pl)
  111.           cells (cdr cells)
  112.     )
  113.     (if (< (distance pc p) mindist)
  114.       (setq rtn t
  115.             cells nil
  116.       )
  117.     )
  118.   )
  119.   rtn
  120. )
  121. ;; Random number generator, Seed must remain global.    LeeMac                ;
  122. ;; Will return a real in the range 0...rng                                    ;
  123.  
  124. (defun rand (rng / x)
  125.   (* (/ (setq x    4294967296.0
  126.               seed (rem (1+ (* 1664525.0
  127.                                (cond (seed)
  128.                                      ((getvar 'DATE))
  129.                                )
  130.                             )
  131.                         )
  132.                         x
  133.                    )
  134.         )
  135.         x
  136.      )
  137.      rng
  138.   )
  139. )
  140.  
  141. ;; Floor function, Returns the largest integer not greater than x.            ;
  142. (defun floor (x)
  143.   (if (minusp (rem x 1))
  144.     (- (fix x) 1)
  145.     (fix x)
  146.   )
  147. )
  148. ;; Ceiling function, Returns the smallest integer not less than x.            ;
  149. (defun ceil (x)
  150.   (if (> (rem x 1) 0)
  151.     (+ (fix x) 1)
  152.     (fix x)
  153.   )
  154. )
  155.  
  156. (defun c:test (/ ** p1 p2 bb md zz wl cp dd nw ch f e pl pll)
  157.  
  158.  
  159.   (command "_.UCS" "_W")
  160.   (setq p1 (getpoint "\nPick a Window Defining Zone: ")
  161.         p2 (getcorner p1)
  162.         ** (vl-cmdf "_.RECTANGLE" "_non" p1 "_non" p2)
  163.         pl (list p1 p2)
  164.         bb (list (apply 'mapcar (cons 'min pl))
  165.                  (apply 'mapcar (cons 'max pl))
  166.            )
  167.         ** (vl-cmdf "_.UCS" "_M" "_non" (car bb))
  168.         bb (mapcar '(lambda (p) (trans p 0 1)) bb)
  169.         md (getdist
  170.              "\nPick or specify Minimum Distance Between Points : "
  171.            )
  172.         zz (getdist
  173.              "\nPick or specify Maximum Elevation above and below 0.0 : "
  174.            )
  175.         wl (getdist
  176.              "\nPick or specify Length of wave period : "
  177.            )
  178.         cp (getpoint
  179.              "\nPick or specify center point of radial waving : "
  180.            )
  181.         dd (car (vl-sort (list (distance cp (car bb)) (distance cp (list (caadr bb) (cadar bb))) (distance cp (cadr bb)) (distance cp (list (caar bb) (cadadr bb)))) '>))
  182.         ** (initget 7)
  183.         nw (getint
  184.              (strcat
  185.                "\nSpecify number of waves along radial axis (must be > "
  186.                (itoa (fix (/ dd wl)))
  187.                ") : "
  188.              )
  189.            )
  190.         ** (entlast)
  191.   )
  192.   (while (<= nw (fix (/ dd wl)))
  193.     (initget 7)
  194.     (setq nw (getint
  195.               (strcat
  196.                 "\nSpecify number of waves along radial axis (must be > "
  197.                 (itoa (fix (/ dd wl)))
  198.                 ") : "
  199.               )
  200.             )
  201.     )
  202.   )
  203.  
  204.   (setq
  205.         pl (bridson (car bb) (cadr bb) md)
  206.         pl (vl-sort pl '(lambda (a b) (< (distance cp a) (distance cp b))))
  207.   )
  208.  
  209.   (initget 1 "Up Down Top Bottom")
  210.   (setq ch (getkword "\nSpecify starting waving option [Up/Down/Top/Bottom] : "))
  211.   (cond
  212.     ( (eq ch "Up")
  213.       (defun f ( x ) (sin x))
  214.     )
  215.     ( (eq ch "Down")
  216.       (defun f ( x ) (- (sin x)))
  217.     )
  218.     ( (eq ch "Top")
  219.       (defun f ( x ) (sin (+ x (* 0.5 pi))))
  220.     )
  221.     ( (eq ch "Bottom")
  222.       (defun f ( x ) (sin (- x (* 0.5 pi))))
  223.     )
  224.   )
  225.  
  226.   (foreach p pl
  227.     (setq e (* zz (f (* (/ (rem (distance cp p) wl) wl) 2.0 pi))))
  228.     (setq p (list (car p) (cadr p) e))
  229.     (setq pll (cons p pll))
  230.   )
  231.  
  232.   (setq pll (reverse pll))
  233.  
  234.   (mapcar '(lambda (a)
  235.              (entmake (list '(0 . "POINT") '(8 . "Point") (cons 10 a)))
  236.            )
  237.           (mapcar '(lambda (b) (trans b 1 0)) pll)
  238.   )
  239.                                         ;(entdel **)
  240.   (princ)
  241. )
  242.  

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

:)

M.R. on Youtube

ymg

  • Guest
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #21 on: May 08, 2015, 12:12:15 PM »
Quote
... I am curious how no one haven't posted remark ab this...

Marko,

I posted Bridson in 2013, never generated any interest.

Seems to be changing.  :-)

ymg

danallen

  • Guest
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #22 on: May 08, 2015, 12:32:16 PM »
for me this post caught my attention showing how an algorithm can differentiate two kinds of random (with a picture!)
http://www.theswamp.org/index.php?topic=45379.msg544989#msg544989

Quote
I posted Bridson in 2013, never generated any interest.

ymg

  • Guest
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #23 on: May 08, 2015, 01:01:31 PM »
for me this post caught my attention showing how an algorithm can differentiate two kinds of random (with a picture!)
http://www.theswamp.org/index.php?topic=45379.msg544989#msg544989


Dan,

Guess the saying "A Picture is Worth a Thousand Words" holds.

ymg

ribarm

  • Gator
  • Posts: 3269
  • Marko Ribar, architect
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #24 on: May 08, 2015, 01:05:40 PM »
I am curious how no one haven't posted remark ab this...

What I mean, I've used RND twice in my previous versions and I thought that someone will notice that I could use sine function instead of imitating waves with RND for elevations...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ymg

  • Guest
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #25 on: May 08, 2015, 01:25:55 PM »
Marko,

You can apply just about any function.

Random is interesting to get variety.

ymg

ribarm

  • Gator
  • Posts: 3269
  • Marko Ribar, architect
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #26 on: May 09, 2015, 05:07:21 AM »
Here is my attempt to implement any function... I didn't know how to separate trigonometric func like sinus from other non-trigonometric, so I've constructed strange (if (or ... ) trigonometric non-trigonometric) statement... I've tested it for only (sin x) and (expt x 2) and it worked... If someone sees something that should be different or have strange results, please post remark...

For X axis elevation distribution :
Code - Auto/Visual Lisp: [Select]
  1. ;;                                                                            ;
  2. ;; Poisson Disk Sampling per Bridson Algorithm                                ;
  3. ;;                                                                            ;
  4. ;; See: http://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf;
  5. ;;      http://devmag.org.za/2009/05/03/poisson-disk-sampling/                ;
  6. ;;                                                                            ;
  7. ;; Will return a Random Set of points with a minimum distance between them    ;
  8. ;;                                                                            ;
  9.  
  10. (defun bridson (ll    ur    mindist     /     a     al    cells cellsize
  11.                 grid  i     ind   k     p     p1    p2    pl    r
  12.                 tcl   x     y
  13.                )
  14.   (setq k        30
  15.         width    (- (car ur) (car ll))
  16.         height   (- (cadr ur) (cadr ll))
  17.         cellSize (/ mindist (sqrt 2))
  18.         x        (ceil (/ width cellsize))
  19.         y        (ceil (/ height cellsize))
  20.         x0       (car ll)
  21.         y0       (cadr ll)
  22.         grid     (vlax-make-safearray vlax-vbInteger (cons 0 x) (cons 0 y))
  23.         p1       (list (rand width) (rand height))
  24.         pl       (list p1)
  25.         al       (list 0)               ; Initialize Active List with index of First Point;
  26.         ind      (mapcar '(lambda (a) (fix (/ a cellsize))) p1)
  27.  
  28.   )
  29.   (init2d grid x y)                     ; Initialize the grid to all -1, then             ;
  30.  
  31.   (vlax-safearray-put-element grid (car ind) (cadr ind) 0)
  32.  
  33.   (setq i 0)
  34.   (while al
  35.     (setq p  (nth (fix (rand (length al))) al)
  36.           p1 (nth p pl)
  37.           p1 (list (car p1) (cadr p1))
  38.     )
  39.     (repeat k
  40.       (setq a   (rand (+ pi pi))
  41.             r   (* mindist (+ 1.0 (rand 1.0)))
  42.             p2  (polar p1 a r)
  43.             ind (mapcar '(lambda (a) (fix (/ a cellsize))) p2)
  44.       )
  45.       (if (and (<= 0 (car p2) width) (<= 0 (cadr p2) height))
  46.         (progn
  47.           (setq cells (ptsaround grid ind))
  48.           (if cells
  49.             (setq tcl (tooclosep p2 cells pl))
  50.             (setq tcl nil)
  51.           )
  52.           (if (not tcl)
  53.             (progn
  54.               (setq i  (1+ i)
  55.                     al (cons i al)
  56.                     pl (append pl (list p2))
  57.               )
  58.  
  59.               (vlax-safearray-put-element grid (car ind) (cadr ind) i)
  60.             )
  61.           )
  62.         )
  63.       )
  64.     )
  65.     (setq al (vl-remove p al))
  66.  
  67.   )
  68.  
  69.   (mapcar '(lambda (a) (list (+ (car a) x0) (+ (cadr a) y0) 0.0))
  70.           pl
  71.   )
  72. )
  73.  
  74. (defun init2d (grid x y / i j)
  75.   (setq i -1)
  76.   (repeat x
  77.     (setq i (1+ i)
  78.           j -1
  79.     )
  80.     (repeat y
  81.       (setq j (1+ j))
  82.       (vlax-safearray-put-element grid i j -1)
  83.     )
  84.   )
  85. )
  86.  
  87.  
  88. (defun ptsaround (grid ind / i j rtn tmp)
  89.  
  90.   (setq j (- (cadr ind) 2))
  91.   (repeat 5
  92.     (setq i (- (car ind) 2))
  93.     (repeat 5
  94.       (if (and (< -1 i x) (< -1 j y))
  95.         (if
  96.           (not (= (setq tmp (vlax-safearray-get-element grid i j)) -1)
  97.           )
  98.            (setq rtn (cons tmp rtn))
  99.         )
  100.       )
  101.       (setq i (1+ i))
  102.     )
  103.     (setq j (1+ j))
  104.   )
  105.   rtn
  106. )
  107.  
  108. (defun tooclosep (p cells pl / pc rtn)
  109.   (while cells
  110.     (setq pc    (nth (car cells) pl)
  111.           cells (cdr cells)
  112.     )
  113.     (if (< (distance pc p) mindist)
  114.       (setq rtn t
  115.             cells nil
  116.       )
  117.     )
  118.   )
  119.   rtn
  120. )
  121. ;; Random number generator, Seed must remain global.    LeeMac                ;
  122. ;; Will return a real in the range 0...rng                                    ;
  123.  
  124. (defun rand (rng / x)
  125.   (* (/ (setq x    4294967296.0
  126.               seed (rem (1+ (* 1664525.0
  127.                                (cond (seed)
  128.                                      ((getvar 'DATE))
  129.                                )
  130.                             )
  131.                         )
  132.                         x
  133.                    )
  134.         )
  135.         x
  136.      )
  137.      rng
  138.   )
  139. )
  140.  
  141. ;; Floor function, Returns the largest integer not greater than x.            ;
  142. (defun floor (x)
  143.   (if (minusp (rem x 1))
  144.     (- (fix x) 1)
  145.     (fix x)
  146.   )
  147. )
  148. ;; Ceiling function, Returns the smallest integer not less than x.            ;
  149. (defun ceil (x)
  150.   (if (> (rem x 1) 0)
  151.     (+ (fix x) 1)
  152.     (fix x)
  153.   )
  154. )
  155.  
  156. (defun c:test (/ ** p1 p2 bb md zz nw f fun dw r h e pl pll)
  157.  
  158.  
  159.   (command "_.UCS" "_W")
  160.   (setq p1 (getpoint "\nPick a Window Defining Zone: ")
  161.         p2 (getcorner p1)
  162.         ** (vl-cmdf "_.RECTANGLE" "_non" p1 "_non" p2)
  163.         pl (list p1 p2)
  164.         bb (list (apply 'mapcar (cons 'min pl))
  165.                  (apply 'mapcar (cons 'max pl))
  166.            )
  167.         ** (vl-cmdf "_.UCS" "_M" "_non" (car bb))
  168.         bb (mapcar '(lambda (p) (trans p 0 1)) bb)
  169.         md (getdist
  170.              "\nPick or specify Minimum Distance Between Points : "
  171.            )
  172.         zz (getdist
  173.              "\nPick or specify Maximum Elevation above and below 0.0 : "
  174.            )
  175.         ** (initget 7)
  176.         nw (getint
  177.              "\nSpecify number of Periods along X axis : "
  178.            )
  179.         ** (entlast)
  180.         pl (bridson (car bb) (cadr bb) md)
  181.         pl (vl-sort pl '(lambda (a b) (< (car a) (car b))))
  182.   )
  183.  
  184.   (setq f (getstring t "\nSpecify function in ALISP notation with \"x\" as parameter...\nSpecification must have starting open and ending close brackets : "))
  185.   (defun fun ( x ) (eval (read f)))
  186.   (setq dw (/ (caadr bb) nw))
  187.   (mapcar '(lambda ( x / k )
  188.       (setq k 0)
  189.       (repeat x
  190.         (setq k (1+ k))
  191.         (if (or
  192.               (equal (fun (* k (/ (* 2.0 pi) x))) 0.0 1e-8)
  193.               (equal (fun (* k (/ (* 2.0 pi) x))) -1.0 1e-8)
  194.               (equal (fun (* k (/ (* 2.0 pi) x))) 1.0 1e-8)
  195.             )
  196.           (setq r (cons t r))
  197.           (setq r (cons nil r))
  198.         )
  199.       )
  200.     )
  201.     '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36)
  202.   )
  203.   (if (apply 'or r)
  204.       (foreach p pl
  205.         (setq e (* zz (/ (if (< 0.0 (rem (car p) (* 2.0 dw)) dw) (fun (* (/ (rem (car p) dw) dw) 2.0 pi)) (fun (- (* (/ (rem (car p) dw) dw) 2.0 pi) (* 2.0 pi)))))))
  206.         (setq p (list (car p) (cadr p) e))
  207.         (setq pll (cons p pll))
  208.       )
  209.     (progn
  210.       (setq h (max (abs (fun dw)) (abs (fun 0.0))))
  211.       (foreach p pl
  212.         (setq e (* zz (/ (if (< 0.0 (rem (car p) (* 2.0 dw)) dw) (fun (rem (car p) dw)) (fun (- (rem (car p) dw) dw))) h)))
  213.         (setq p (list (car p) (cadr p) e))
  214.         (setq pll (cons p pll))
  215.       )
  216.     )
  217.   )
  218.  
  219.   (setq pll (reverse pll))
  220.  
  221.   (mapcar '(lambda (a)
  222.              (entmake (list '(0 . "POINT") '(8 . "Point") (cons 10 a)))
  223.            )
  224.           (mapcar '(lambda (b) (trans b 1 0)) pll)
  225.   )
  226.                                         ;(entdel **)
  227.   (princ)
  228. )
  229.  

For radial elevation distribution :
Code - Auto/Visual Lisp: [Select]
  1. ;;                                                                            ;
  2. ;; Poisson Disk Sampling per Bridson Algorithm                                ;
  3. ;;                                                                            ;
  4. ;; See: http://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf;
  5. ;;      http://devmag.org.za/2009/05/03/poisson-disk-sampling/                ;
  6. ;;                                                                            ;
  7. ;; Will return a Random Set of points with a minimum distance between them    ;
  8. ;;                                                                            ;
  9.  
  10. (defun bridson (ll    ur    mindist     /     a     al    cells cellsize
  11.                 grid  i     ind   k     p     p1    p2    pl    r
  12.                 tcl   x     y
  13.                )
  14.   (setq k        30
  15.         width    (- (car ur) (car ll))
  16.         height   (- (cadr ur) (cadr ll))
  17.         cellSize (/ mindist (sqrt 2))
  18.         x        (ceil (/ width cellsize))
  19.         y        (ceil (/ height cellsize))
  20.         x0       (car ll)
  21.         y0       (cadr ll)
  22.         grid     (vlax-make-safearray vlax-vbInteger (cons 0 x) (cons 0 y))
  23.         p1       (list (rand width) (rand height))
  24.         pl       (list p1)
  25.         al       (list 0)               ; Initialize Active List with index of First Point;
  26.         ind      (mapcar '(lambda (a) (fix (/ a cellsize))) p1)
  27.  
  28.   )
  29.   (init2d grid x y)                     ; Initialize the grid to all -1, then             ;
  30.  
  31.   (vlax-safearray-put-element grid (car ind) (cadr ind) 0)
  32.  
  33.   (setq i 0)
  34.   (while al
  35.     (setq p  (nth (fix (rand (length al))) al)
  36.           p1 (nth p pl)
  37.           p1 (list (car p1) (cadr p1))
  38.     )
  39.     (repeat k
  40.       (setq a   (rand (+ pi pi))
  41.             r   (* mindist (+ 1.0 (rand 1.0)))
  42.             p2  (polar p1 a r)
  43.             ind (mapcar '(lambda (a) (fix (/ a cellsize))) p2)
  44.       )
  45.       (if (and (<= 0 (car p2) width) (<= 0 (cadr p2) height))
  46.         (progn
  47.           (setq cells (ptsaround grid ind))
  48.           (if cells
  49.             (setq tcl (tooclosep p2 cells pl))
  50.             (setq tcl nil)
  51.           )
  52.           (if (not tcl)
  53.             (progn
  54.               (setq i  (1+ i)
  55.                     al (cons i al)
  56.                     pl (append pl (list p2))
  57.               )
  58.  
  59.               (vlax-safearray-put-element grid (car ind) (cadr ind) i)
  60.             )
  61.           )
  62.         )
  63.       )
  64.     )
  65.     (setq al (vl-remove p al))
  66.  
  67.   )
  68.  
  69.   (mapcar '(lambda (a) (list (+ (car a) x0) (+ (cadr a) y0) 0.0))
  70.           pl
  71.   )
  72. )
  73.  
  74. (defun init2d (grid x y / i j)
  75.   (setq i -1)
  76.   (repeat x
  77.     (setq i (1+ i)
  78.           j -1
  79.     )
  80.     (repeat y
  81.       (setq j (1+ j))
  82.       (vlax-safearray-put-element grid i j -1)
  83.     )
  84.   )
  85. )
  86.  
  87.  
  88. (defun ptsaround (grid ind / i j rtn tmp)
  89.  
  90.   (setq j (- (cadr ind) 2))
  91.   (repeat 5
  92.     (setq i (- (car ind) 2))
  93.     (repeat 5
  94.       (if (and (< -1 i x) (< -1 j y))
  95.         (if
  96.           (not (= (setq tmp (vlax-safearray-get-element grid i j)) -1)
  97.           )
  98.            (setq rtn (cons tmp rtn))
  99.         )
  100.       )
  101.       (setq i (1+ i))
  102.     )
  103.     (setq j (1+ j))
  104.   )
  105.   rtn
  106. )
  107.  
  108. (defun tooclosep (p cells pl / pc rtn)
  109.   (while cells
  110.     (setq pc    (nth (car cells) pl)
  111.           cells (cdr cells)
  112.     )
  113.     (if (< (distance pc p) mindist)
  114.       (setq rtn t
  115.             cells nil
  116.       )
  117.     )
  118.   )
  119.   rtn
  120. )
  121. ;; Random number generator, Seed must remain global.    LeeMac                ;
  122. ;; Will return a real in the range 0...rng                                    ;
  123.  
  124. (defun rand (rng / x)
  125.   (* (/ (setq x    4294967296.0
  126.               seed (rem (1+ (* 1664525.0
  127.                                (cond (seed)
  128.                                      ((getvar 'DATE))
  129.                                )
  130.                             )
  131.                         )
  132.                         x
  133.                    )
  134.         )
  135.         x
  136.      )
  137.      rng
  138.   )
  139. )
  140.  
  141. ;; Floor function, Returns the largest integer not greater than x.            ;
  142. (defun floor (x)
  143.   (if (minusp (rem x 1))
  144.     (- (fix x) 1)
  145.     (fix x)
  146.   )
  147. )
  148. ;; Ceiling function, Returns the smallest integer not less than x.            ;
  149. (defun ceil (x)
  150.   (if (> (rem x 1) 0)
  151.     (+ (fix x) 1)
  152.     (fix x)
  153.   )
  154. )
  155.  
  156. (defun c:test (/ ** p1 p2 bb md zz wl cp dd nw f fun r h e pl pll)
  157.  
  158.  
  159.   (command "_.UCS" "_W")
  160.   (setq p1 (getpoint "\nPick a Window Defining Zone: ")
  161.         p2 (getcorner p1)
  162.         ** (vl-cmdf "_.RECTANGLE" "_non" p1 "_non" p2)
  163.         pl (list p1 p2)
  164.         bb (list (apply 'mapcar (cons 'min pl))
  165.                  (apply 'mapcar (cons 'max pl))
  166.            )
  167.         ** (vl-cmdf "_.UCS" "_M" "_non" (car bb))
  168.         bb (mapcar '(lambda (p) (trans p 0 1)) bb)
  169.         md (getdist
  170.              "\nPick or specify Minimum Distance Between Points : "
  171.            )
  172.         zz (getdist
  173.              "\nPick or specify Maximum Elevation above and below 0.0 : "
  174.            )
  175.         wl (getdist
  176.              "\nPick or specify Length of wave period : "
  177.            )
  178.         cp (getpoint
  179.              "\nPick or specify center point of radial waving : "
  180.            )
  181.         dd (car (vl-sort (list (distance cp (car bb)) (distance cp (list (caadr bb) (cadar bb))) (distance cp (cadr bb)) (distance cp (list (caar bb) (cadadr bb)))) '>))
  182.         ** (initget 7)
  183.         nw (getint
  184.              (strcat
  185.                "\nSpecify number of waves along radial axis (must be > "
  186.                (itoa (fix (/ dd wl)))
  187.                ") : "
  188.              )
  189.            )
  190.         ** (entlast)
  191.   )
  192.   (while (<= nw (fix (/ dd wl)))
  193.     (initget 7)
  194.     (setq nw (getint
  195.               (strcat
  196.                 "\nSpecify number of waves along radial axis (must be > "
  197.                 (itoa (fix (/ dd wl)))
  198.                 ") : "
  199.               )
  200.             )
  201.     )
  202.   )
  203.  
  204.   (setq
  205.         pl (bridson (car bb) (cadr bb) md)
  206.         pl (vl-sort pl '(lambda (a b) (< (distance cp a) (distance cp b))))
  207.   )
  208.  
  209.   (setq f (getstring t "\nSpecify function in ALISP notation with \"x\" as parameter...\nSpecification must have starting open and ending close brackets : "))
  210.   (defun fun ( x ) (eval (read f)))
  211.   (mapcar '(lambda ( x / k )
  212.       (setq k 0)
  213.       (repeat x
  214.         (setq k (1+ k))
  215.         (if (or
  216.               (equal (fun (* k (/ (* 2.0 pi) x))) 0.0 1e-8)
  217.               (equal (fun (* k (/ (* 2.0 pi) x))) -1.0 1e-8)
  218.               (equal (fun (* k (/ (* 2.0 pi) x))) 1.0 1e-8)
  219.             )
  220.           (setq r (cons t r))
  221.           (setq r (cons nil r))
  222.         )
  223.       )
  224.     )
  225.     '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36)
  226.   )
  227.   (if (apply 'or r)
  228.       (foreach p pl
  229.         (setq e (* zz (/ (if (< 0.0 (rem (distance cp p) (* 2.0 wl)) wl) (fun (* (/ (rem (distance cp p) wl) wl) 2.0 pi)) (fun (- (* (/ (rem (distance cp p) wl) wl) 2.0 pi) (* 2.0 pi)))))))
  230.         (setq p (list (car p) (cadr p) e))
  231.         (setq pll (cons p pll))
  232.       )
  233.     (progn
  234.       (setq h (max (abs (fun wl)) (abs (fun 0.0))))
  235.       (foreach p pl
  236.         (setq e (* zz (/ (if (< 0.0 (rem (distance cp p) (* 2.0 wl)) wl) (fun (rem (distance cp p) wl)) (fun (- (rem (distance cp p) wl) wl))) h)))
  237.         (setq p (list (car p) (cadr p) e))
  238.         (setq pll (cons p pll))
  239.       )
  240.     )
  241.   )
  242.  
  243.   (setq pll (reverse pll))
  244.  
  245.   (mapcar '(lambda (a)
  246.              (entmake (list '(0 . "POINT") '(8 . "Point") (cons 10 a)))
  247.            )
  248.           (mapcar '(lambda (b) (trans b 1 0)) pll)
  249.   )
  250.                                         ;(entdel **)
  251.   (princ)
  252. )
  253.  

Thanks, M.R.
« Last Edit: May 10, 2015, 07:04:18 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3269
  • Marko Ribar, architect
Re: Poisson Disk Sampling - Bridson Algorithm - Blue Noise
« Reply #27 on: May 10, 2015, 07:21:40 AM »
It seems that no one doesn't check 2 last posted lisps... There was a problem with circle/sphere function and no one reported... It should work now... You should have checked with function (+- (sqrt (abs (- (expt r 2) (expt x 2))))) where r is radius (period length or elevation above and below 0.0)... How disappointing... :-(
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube