Jump to content

Recommended Posts

Posted

Random points on cube

(defun randompointsoncube ( / face rand)
 (setq face
        (nth (rem (dos_random) 6)
             '((nil nil 0.0) (nil nil 1.0)
               (nil 0.0 nil) (nil 1.0 nil)
               (0.0 nil nil) (1.0 nil nil)
               )
             )
       rand (list
              (/ (dos_random) 32767.0)
              (/ (dos_random) 32767.0)
              (/ (dos_random) 32767.0)
              )
       )
 (entmake (list '(0 . "POINT") (cons 10 (mapcar '(lambda (x y) (if x x y)) face rand))))
 )

(defun C:TEST ( / i)
 (if
   (setq i (getint"\nNumber of points: "))
   (repeat i (randompointsoncube))
   )
 (princ)
 )

Replace (dos_random) with your own random generator.

  • Replies 45
  • Created
  • Last Reply

Top Posters In This Topic

  • Lee Mac

    9

  • pBe

    9

  • brams

    9

  • MSasu

    7

Top Posters In This Topic

Posted Images

Posted

This is a nice and efective one, Stefan. Atanasiu?

Posted

How come it only creates points on only 3 faces of the cube?

Posted
This is a nice and efective one, Stefan. Atanasiu?

Thank you Mircea.

Nu Atanasiu.... Muntean

How come it only creates points on only 3 faces of the cube?

Its working here, points on all 6 faces...

 

Another one, added random color and "orientation" of points.

 

(defun randompointsoncube ( / face)
 (setq face
        (nth (rem (dos_random) 6)
             '((nil nil 0.0) (nil nil 1.0)
               (nil 0.0 nil) (nil 1.0 nil)
               (0.0 nil nil) (1.0 nil nil)
               )
             )
       )
 (entmake (list
            '(0 . "POINT")
            (cons  10 (mapcar '(lambda (x) (if x x (/ (dos_random) 32767.0))) face))
            (cons  62 (rem (dos_random) 256))
            (cons 210 (mapcar '(lambda (x) (if x 1.0 0.0)) face))
            )
          )
 )

(defun C:TEST ( / i)
 (setvar 'pdmode   34)
 (setvar 'pdsize 0.01)
 (if
   (setq i (getint"\nNumber of points: "))
   (repeat i (randompointsoncube))
   )
 (princ)
 )

Posted

Thanks guys! Perfect!

Multumesc, Stefan si Mircea. La Multi Ani! pentru Mircea :)

Posted

Its working here, points on all 6 faces...

 

My bad. Had to tweak the Random generator i'm using. Now its good. :)

 

Excellent work Stefan BMR.

Posted

What about a cone? Or a revolved surface...

  • 1 month later...
Posted
What about a cone? Or a revolved surface...

(defun C:TEST ( / cone p r h i u z)
 (defun cone (/ x y d)
   (setq x (- r (* (/ (dos_random) 16383.5) r)); (* r (- 1.0 (/ (dos_random) 16383.5)))
         y (- r (* (/ (dos_random) 16383.5) r))
         d (sqrt (+ (* x x) (* y y)))
   )
   (if
     (> d r)
      (cone)
      (entmake
        (list
          '(0 . "POINT")
          (cons 10 (mapcar '+ p (list x y (* (- r d) u))))
          (cons 62 (rem (dos_random) 256))
          (cons 210
                (list
                  (* (cos (atan y x)) z u)
                  (* (sin (atan y x)) z u)
                  z
                )
          )
        )
      )
   )
 )
 (if
   (and
     (setq p (getpoint  "\nBase center: "))
     (setq r (getdist p "\nBase radius: "))
     (setq h (getdist p "\nCone height: "))
     (setq i (getint "\nNumber of points: "))
     )
   (progn
     (setq u (/ h r)
           z (cos (atan u))
           )
     (repeat i (cone))
     )
   )
 (princ)
 )

Posted

My version of point-sphere:

 

(defun pointsphere ( r / a b p )
   (setq a (* (LM:random) pi)
         b (* (LM:random) (+ pi pi))
         p (list (* r (sin a) (cos b)) (* r (sin a) (sin b)) (* r (cos a)))
   )
   (entmake (list '(0 . "POINT") (cons 010 p) (cons 62 (fix (* (LM:random) 255))) (cons 210 p)))
)

(defun LM:random ( / x )
   (/ (setq x 4294967296.0 seed (rem (1+ (* 1664525.0 (cond (seed) ((getvar 'DATE))))) x)) x)
)

(defun c:test ( / r x )
   (if (and
           (setq x (getint "\nNumber of Points: "))
           (setq r (getdist  "\nRadius: " '(0.0 0.0 0.0)))
       )
       (repeat x (pointsphere r))
   )
   (princ)
)

Posted

Nice Lee, but you have accumulation points on pole. Try 10 000 points and see.

Pseudo-random algorithms gives a very uniform distributions in a given interval.

Your method generates 2 numbers, x and y. This will give you a rectangle (0 0) (x y) filled uniformly with "random" points. (In my opinion, a uniform distribution is not so random...)

Now, get this rectangle and fold it around a sphere. The result is a higher density at the pole.

And this was the issue that Bill Gilliss mentioned in the original post.

8th post in that thread is mine, but I guess if I should do it today, it would be different.

Posted

Good point Stefan, a result of distributing the random linear point interval of 0 - pi using the cosine function. I would think the solution would be to create a random distribution of points along a cosine wave, though, I have no idea how to achieve that.

Posted (edited)

My idea (similar to cone surface):

Generate 3 numbers between -r ad r (sphere radius). This will fill a cube with random points. The points outside the sphere need to be eliminate, because

if we project now those points on a sphere surface, some area will be more dense. (see mentioned thread on autodesk)

Now we have a volume of sphere, filled (randomly) with points. Project them on sphere surface and... voila!!

Not a efficient method, but the result is just fine.

(defun C:TEST ( / sphere p r h i u z)
 (defun sphere (/ x y z d)
   (setq x (- r (* (/ (dos_random) 16383.5) r)); (* r (- 1.0 (/ (dos_random) 16383.5)))
         y (- r (* (/ (dos_random) 16383.5) r))
         z (- r (* (/ (dos_random) 16383.5) r))
         d (sqrt (+ (* x x) (* y y) (* z z)))
   )
   (if
     (> d r)
      (sphere)
      (entmake
        (list
          '(0 . "POINT")
          (cons 10 (mapcar '(lambda (a b) (+ b (/ (* a r) d))) (list x y z) p))
          (cons 62 (rem (dos_random) 256))
          (cons 210 (list x y z))
        )
      )
   )
 )
 (if
   (and
     (setq p (getpoint  "\nCenter: "))
     (setq r (getdist p "\nRadius: "))
     (setq i (getint "\nNumber of points: "))
     )
    (repeat i (sphere))
   )
 (princ)
 )

Edit: No need to unitize 210 value. (x y z) works as well.

Edited by Stefan BMR
Posted

Nice idea Stefan :)

 

A couple of minor points: I think the sphere centre needs to be 0,0,0 for the points to look correct, as the 210 normal vector is expressed relative to the WCS Origin, not the centre of the sphere, also (cons 210 (list x y z)) == (list 210 x y z) :)

Posted
Nice idea Stefan :)

A couple of minor points: I think the sphere centre needs to be 0,0,0 for the points to look correct, as the 210 normal vector is expressed relative to the WCS Origin, not the centre of the sphere, also (cons 210 (list x y z)) == (list 210 x y z) :)

Don't think so, Lee. (x y z) is relative to 0,0,0 since they are in range [-r, r]. (210 x y z) is too.

Then adding p to (x y z) will just move points from0,0,0 to p. It looks OK here.

points_on_sphere.png

Posted
Don't think so, Lee. (x y z) is relative to 0,0,0 since they are in range [-r, r]. (210 x y z) is too.

Then adding p to (x y z) will just move points from0,0,0 to p. It looks OK here.

[ATTACH=CONFIG]35798[/ATTACH]

 

Oops! Yes, you're absolutely right.

Sorry I should've tested it before jumping to conclusions - as you've gathered, I assumed that (x y z) was the point on the sphere. :oops:

  • 4 months later...
Posted
My version of point-sphere:

 

(defun pointsphere ( r / a b p )
   (setq a (* (LM:random) pi)
         b (* (LM:random) (+ pi pi))
         p (list (* r (sin a) (cos b)) (* r (sin a) (sin b)) (* r (cos a)))
   )
   (entmake (list '(0 . "POINT") (cons 010 p) (cons 62 (fix (* (LM:random) 255))) (cons 210 p)))
)

(defun LM:random ( / x )
   (/ (setq x 4294967296.0 seed (rem (1+ (* 1664525.0 (cond (seed) ((getvar 'DATE))))) x)) x)
)

(defun c:test ( / r x )
   (if (and
           (setq x (getint "\nNumber of Points: "))
           (setq r (getdist  "\nRadius: " '(0.0 0.0 0.0)))
       )
       (repeat x (pointsphere r))
   )
   (princ)
)

 

Nice routine!

 

Lee,

Is it possible to provide a variant that just draw random points but inscribed in a circle in 2D?

 

Tanks!

Posted
Nice routine!

 

Lee,

Is it possible to provide a variant that just draw random points but inscribed in a circle in 2D?

 

Tanks!

 

Sure (using rand from here):

([color=BLUE]defun[/color] pointcircle ( r [color=BLUE]/[/color] a )
   ([color=BLUE]setq[/color] a ([color=BLUE]*[/color] (LM:rand) ([color=BLUE]+[/color] [color=BLUE]pi[/color] [color=BLUE]pi[/color]))
         r ([color=BLUE]*[/color] r (LM:rand))
   )
   ([color=BLUE]entmake[/color]
       ([color=BLUE]list[/color] '(0 . [color=MAROON]"POINT"[/color])
           ([color=BLUE]list[/color] 10 ([color=BLUE]*[/color] r ([color=BLUE]cos[/color] a)) ([color=BLUE]*[/color] r ([color=BLUE]sin[/color] a)) 0.0)
           ([color=BLUE]cons[/color] 62 ([color=BLUE]fix[/color] ([color=BLUE]*[/color] (LM:rand) 255)))
       )
   )
)

[color=GREEN];; Rand  -  Lee Mac[/color]
[color=GREEN];; PRNG implementing a linear congruential generator with[/color]
[color=GREEN];; parameters derived from the book 'Numerical Recipes'[/color]

([color=BLUE]defun[/color] LM:rand ( [color=BLUE]/[/color] a c m )
   ([color=BLUE]setq[/color] m   4294967296.0
         a   1664525.0
         c   1013904223.0
         $xn ([color=BLUE]rem[/color] ([color=BLUE]+[/color] c ([color=BLUE]*[/color] a ([color=BLUE]cond[/color] ($xn) (([color=BLUE]getvar[/color] 'date))))) m)
   )
   ([color=BLUE]/[/color] $xn m)
)

([color=BLUE]defun[/color] c:test ( [color=BLUE]/[/color] r x )
   ([color=BLUE]if[/color] ([color=BLUE]and[/color]
           ([color=BLUE]setq[/color] x ([color=BLUE]getint[/color] [color=MAROON]"\nNumber of Points: "[/color]))
           ([color=BLUE]setq[/color] r ([color=BLUE]getdist[/color]  [color=MAROON]"\nRadius: "[/color] '(0.0 0.0)))
       )
       ([color=BLUE]repeat[/color] x (pointcircle r))
   )
   ([color=BLUE]princ[/color])
)

Though note that points will be concentrated at the circle centre for the reasons discussed in this thread - Stefan proposes an alternative method to avoid this issue above.

 

Lee

  • 2 weeks later...
Posted

Here is another function to achieve a uniform random distribution of points on a sphere, using the method described here:

 

([color=BLUE]defun[/color] pointsphere ( c r [color=BLUE]/[/color] a b p )
   ([color=BLUE]setq[/color] a (acos ([color=BLUE]1-[/color] ([color=BLUE]*[/color] 2.0 (LM:rand))))
         b ([color=BLUE]*[/color] (LM:rand) ([color=BLUE]+[/color] [color=BLUE]pi[/color] [color=BLUE]pi[/color]))
         p ([color=BLUE]list[/color] ([color=BLUE]*[/color] r ([color=BLUE]sin[/color] a) ([color=BLUE]cos[/color] b)) ([color=BLUE]*[/color] r ([color=BLUE]sin[/color] a) ([color=BLUE]sin[/color] b)) ([color=BLUE]*[/color] r ([color=BLUE]cos[/color] a)))
   )
   ([color=BLUE]entmake[/color]
       ([color=BLUE]list[/color]
          '(0 . [color=MAROON]"POINT"[/color])
           ([color=BLUE]cons[/color] 010 ([color=BLUE]mapcar[/color] '[color=BLUE]+[/color] c p))
           ([color=BLUE]cons[/color] 062 ([color=BLUE]fix[/color] ([color=BLUE]1+[/color] ([color=BLUE]*[/color] (LM:rand) 254))))
           ([color=BLUE]cons[/color] 210 p)
       )
   )
)

[color=GREEN];; Rand  -  Lee Mac[/color]
[color=GREEN];; PRNG implementing a linear congruential generator with[/color]
[color=GREEN];; parameters derived from the book 'Numerical Recipes'[/color]

([color=BLUE]defun[/color] LM:rand ( [color=BLUE]/[/color] a c m )
   ([color=BLUE]setq[/color] m   4294967296.0
         a   1664525.0
         c   1013904223.0
         $xn ([color=BLUE]rem[/color] ([color=BLUE]+[/color] c ([color=BLUE]*[/color] a ([color=BLUE]cond[/color] ($xn) (([color=BLUE]getvar[/color] 'date))))) m)
   )
   ([color=BLUE]/[/color] $xn m)
)

[color=GREEN];; ArcCosine  -  Lee Mac[/color]
[color=GREEN];; Args: -1 <= x <= 1[/color]

([color=BLUE]defun[/color] acos ( x )
   ([color=BLUE]if[/color] ([color=BLUE]<=[/color] -1.0 x 1.0)
       ([color=BLUE]atan[/color] ([color=BLUE]sqrt[/color] ([color=BLUE]-[/color] 1.0 ([color=BLUE]*[/color] x x))) x)
   )
)

([color=BLUE]defun[/color] c:test ( [color=BLUE]/[/color] c r x )
   ([color=BLUE]if[/color]
       ([color=BLUE]and[/color]
           ([color=BLUE]setq[/color] x ([color=BLUE]getint[/color] [color=MAROON]"\nNumber of Points: "[/color]))
           ([color=BLUE]setq[/color] c ([color=BLUE]getpoint[/color] [color=MAROON]"\nCenter: "[/color]))
           ([color=BLUE]setq[/color] r ([color=BLUE]getdist[/color]  [color=MAROON]"\nRadius: "[/color] c))
       )
       ([color=BLUE]repeat[/color] x (pointsphere ([color=BLUE]trans[/color] c 1 0) r))
   )
   ([color=BLUE]princ[/color])
)

Posted
Here is another function to achieve a uniform random distribution of points on a sphere, using the method described here:

 

([color=BLUE]defun[/color] pointsphere ( c r [color=BLUE]/[/color] a b p )
   ([color=BLUE]setq[/color] a (acos ([color=BLUE]1-[/color] ([color=BLUE]*[/color] 2.0 (LM:rand))))
         b ([color=BLUE]*[/color] (LM:rand) ([color=BLUE]+[/color] [color=BLUE]pi[/color] [color=BLUE]pi[/color]))
         p ([color=BLUE]list[/color] ([color=BLUE]*[/color] r ([color=BLUE]sin[/color] a) ([color=BLUE]cos[/color] b)) ([color=BLUE]*[/color] r ([color=BLUE]sin[/color] a) ([color=BLUE]sin[/color] b)) ([color=BLUE]*[/color] r ([color=BLUE]cos[/color] a)))
   )
   ([color=BLUE]entmake[/color]
       ([color=BLUE]list[/color]
          '(0 . [color=MAROON]"POINT"[/color])
           ([color=BLUE]cons[/color] 010 ([color=BLUE]mapcar[/color] '[color=BLUE]+[/color] c p))
           ([color=BLUE]cons[/color] 062 ([color=BLUE]fix[/color] ([color=BLUE]1+[/color] ([color=BLUE]*[/color] (LM:rand) 254))))
           ([color=BLUE]cons[/color] 210 p)
       )
   )
)

[color=GREEN];; Rand  -  Lee Mac[/color]
[color=GREEN];; PRNG implementing a linear congruential generator with[/color]
[color=GREEN];; parameters derived from the book 'Numerical Recipes'[/color]

([color=BLUE]defun[/color] LM:rand ( [color=BLUE]/[/color] a c m )
   ([color=BLUE]setq[/color] m   4294967296.0
         a   1664525.0
         c   1013904223.0
         $xn ([color=BLUE]rem[/color] ([color=BLUE]+[/color] c ([color=BLUE]*[/color] a ([color=BLUE]cond[/color] ($xn) (([color=BLUE]getvar[/color] 'date))))) m)
   )
   ([color=BLUE]/[/color] $xn m)
)

[color=GREEN];; ArcCosine  -  Lee Mac[/color]
[color=GREEN];; Args: -1 <= x <= 1[/color]

([color=BLUE]defun[/color] acos ( x )
   ([color=BLUE]if[/color] ([color=BLUE]<=[/color] -1.0 x 1.0)
       ([color=BLUE]atan[/color] ([color=BLUE]sqrt[/color] ([color=BLUE]-[/color] 1.0 ([color=BLUE]*[/color] x x))) x)
   )
)

([color=BLUE]defun[/color] c:test ( [color=BLUE]/[/color] c r x )
   ([color=BLUE]if[/color]
       ([color=BLUE]and[/color]
           ([color=BLUE]setq[/color] x ([color=BLUE]getint[/color] [color=MAROON]"\nNumber of Points: "[/color]))
           ([color=BLUE]setq[/color] c ([color=BLUE]getpoint[/color] [color=MAROON]"\nCenter: "[/color]))
           ([color=BLUE]setq[/color] r ([color=BLUE]getdist[/color]  [color=MAROON]"\nRadius: "[/color] c))
       )
       ([color=BLUE]repeat[/color] x (pointsphere ([color=BLUE]trans[/color] c 1 0) r))
   )
   ([color=BLUE]princ[/color])
)

 

 

Lee,

Best. In fact there is a better distribution of points.

Tanks!

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...