Advertisement

Random point in circle...

Started by December 26, 2001 05:20 PM
40 comments, last by VanKurt 23 years, 1 month ago
quote:
Original post by Null and Void
ZealousElixir, your version only finds a point on the outside of the circle (not any point within the circle).


This is true. My bad. See below for the new version.

quote:

Also, yours will be less random due to your use of the low order bits (you're using modulo instead of division to cap the random value).



Bullcrap.

quote:

Beer Hunter, what I mean was: what if every x returned is 0 and every 0 returned is 0? The point 0,0 isn't going to be in the circle. Well, that isn't very likely, I know. But, there's someodd other points that aren't in the circle either. So, what if every other value is rejected because of that? The algorithm could take a very long time to finally pick a point inside the circle if you're unlucky. If you're really unlucky, the algorithm could never complete!


With millons of these calls happening per second, the odds of that are not even worth considering. Granted, the method he's suggesting is freaking slow.

Here's my way:

    #include <stdlib.h>#include <time.h>#include <math.h>#define PIOVER180 (3.14156/180)...time_t t; srand((unsigned int)time(&t));...float angle = float(rand()%360);float radius = 5; //whatever.float randradius = rand()%radius;float x = float(sin(angle*PIOVER180) * randradius);float y = float(cos(angle*PIOVER180) * randradius);...    


Tada.

Later,
ZE.


Edited by - ZealousElixir on December 27, 2001 10:27:43 PM

[twitter]warrenm[/twitter]

Ripped from "man 3 rand":
quote:

In Numerical Recipes in C: The Art of Scientific Computing ( William H. Press, Brian P. Flannery, Saul A. Teukolsky,W illiam T. Vetterling; New York: Cambridge University Press, 1992 (2nd ed., p. 277)), the following comments are made:

    "If you want to generate a random integer between 1 and 10, you should always do it by using high-order bits, as in
    j=1+(int)(10.0*rand()/(RAND_MAX+1.0));
    and never by anything resembling
    j=1+(rand() % 10);
    (which uses lower-order bits)."




[Resist Windows XP''s Invasive Production Activation Technology!]
Advertisement
I still say it makes no difference. Can you provide a bit more logic for your argument?

Later,
ZE.

[twitter]warrenm[/twitter]

the angle and radius way is very bad, you get higher point density near the center. Do it the box way. You will usually get a hit on the first iteration. There is virtually no chance that it will go beyond a few.
Let''s use a 1 byte system for simplicity. The rand function now returns a value between 0 and 255 (inclusive, of course). If we use modulo 30 to clamp the value to 0 to 29 each number will be clamped to:
0	1	2	3	4	5	6	7	8	910	11	12	13	14	15	16	17	18	1920	21	22	23	24	25	26	27	28	290	1	2	3	4	5	6	7	8	910	11	12	13	14	15	16	17	18	1920	21	22	23	24	25	26	27	28	290	1	2	3	4	5	6	7	8	910	11	12	13	14	15	16	17	18	1920	21	22	23	24	25	26	27	28	290	1	2	3	4	5	6	7	8	910	11	12	13	14	15	16	17	18	1920	21	22	23	24	25	26	27	28	290	1	2	3	4	5	6	7	8	910	11	12	13	14	15	16	17	18	1920	21	22	23	24	25	26	27	28	290	1	2	3	4	5	6	7	8	910	11	12	13	14	15	16	17	18	1920	21	22	23	24	25	26	27	28	290	1	2	3	4	5	6	7	8	910	11	12	13	14	15	16	17	18	1920	21	22	23	24	25	26	27	28	290	1	2	3	4	5	6	7	8	910	11	12	13	14	15	16	17	18	1920	21	22	23	24	25	26	27	28	290	1	2	3	4	5	6	7	8	910	11	12	13	14	15

If we add up the occurances of each number we find that:
0 occurs 9 times1 occurs 9 times2 occurs 9 times3 occurs 9 times4 occurs 9 times5 occurs 9 times6 occurs 9 times7 occurs 9 times8 occurs 9 times9 occurs 9 times10 occurs 9 times11 occurs 9 times12 occurs 9 times13 occurs 9 times14 occurs 9 times15 occurs 9 times16 occurs 8 times17 occurs 8 times18 occurs 8 times19 occurs 8 times20 occurs 8 times21 occurs 8 times22 occurs 8 times23 occurs 8 times24 occurs 8 times25 occurs 8 times26 occurs 8 times27 occurs 8 times28 occurs 8 times29 occurs 8 times

Look, the upper ones have a lower probability of occurance ! Yes, I wrote a program to do that, I''m too lazy to add that up myself .

[Resist Windows XP''s Invasive Production Activation Technology!]
*screams "COINCIDENCE!" and runs and hides in the corner*

Darn.
ZE.

[twitter]warrenm[/twitter]

Advertisement
quote:
Original post by Anonymous Poster
The angle and radius way is very bad, you get higher point density near the center.

Hmm, you''re right. I hadn''t thought about that. You can use a curve function to undo (to ''reweight'') that though, since each radii has a probability inversely proportional to its circumference. I''m working on the equation, it may take me a second to prove it''s correct though .

[Resist Windows XP''s Invasive Production Activation Technology!]
Ok, I'm not quite sure I've proven it, but this seems to generate them more uniformly:
    int X, Y;double Angle, Mag;Angle = (rand()/RAND_MAX)*6.283185307;Mag = (rand()/RAND_MAX)*RadiusOfCircle;Mag = RadiusOfCircle-((Mag * Mag)/RadiusOfCircle);X = ((int)(cos(Angle) * Mag))+CenterX;Y = ((int)(sin(Angle) * Mag))+CenterY;  

Hopefully I didn't make any typos converting that from theory to code . Edit: I fixed a typo .

[Resist Windows XP's Invasive Production Activation Technology!]

Edited by - Null and Void on December 28, 2001 3:54:36 PM
Aww..

Here´s my version

    long x = rand() % (radius*2) - radius,     y = rand() % (radius*2) - radius;while(x*x + y*y > radius*radius){    x = rand() % (radius*2) - radius;    y = rand() % (radius*2) - radius;}long realx = x + xcenter,     realy = y + ycenter;    

Basically picks a point, and sees if it´s valid...

This makes that you can get any point in the cirlce, since you guys seem to use sin and cos in eccessiveness(or however it´s spelled )
Tho that piece of code could be seriously optimized...But I´m just too lazy :D

Edited by - Tjoppen on December 28, 2001 5:29:57 AM
delete this;
Here's my random number code:
// Generate a random number between min and maxtemplate T Random(const T min, const T max){    return min + T ( double(rand()) * double(max-min) / double(RAND_MAX) );}  

This generates a random number in the range of [min, max]. For a [min, max) range, change RAND_MAX to RAND_MAX+1.

Use this with the box method and the random points should be pretty much uniformly distributed across the circle.

Edited by - Scarab0 on December 28, 2001 7:10:11 AM
Dirk =[Scarab]= Gerrits

This topic is closed to new replies.

Advertisement