Question

I want to generate N points within a square (uniformly). how i can achieve this ?

Was it helpful?

Solution

Pretty cool problem, and a lot harder than I imagined but here's the idea. There are papers on this for n-gons but I will just do the square. So uniform distribution from a circle is a common problem and you can't just sample the radius, r, and the angle, theta, independently since more weight is given to a large radius, ie if we take an infinitismally small annulus, you have more area coming from a larger radius further away from the center so we sample uniformly from r^2 since the area is a function of r^2.

Now the idea is similar for a rectangle, its symmetry lends itself to be captured with a some measure of rotation (angle) and distance from origin (radius) but notice that the radius changes dramatically as you rotate about a circle, goes up then down then up then down. we need a way to prescribe the radius based on the angle so its mass at about any given point is uniform.

Consider the following construction (we can orient the square such that it sits on one of its sides but this is more intuitive) Sorry my diagrams are badly drawn

                             A

                                  X

                  B          O          C



                             D

Here is our square, with A,B,C,D being the corners and O being the origin. We'll explain X later. Let's start at the point C and rotate counterclockwise and the angle will be denoted Theta. X is the point of intersection with the edge of the square if we draw a line from O with angle Theta. In other words, X = r(Theta). What we are trying to do is capture the distance r as a function of theta as to make this a uniform probability distribution of Theta. That's the whole idea..

we can write the following with the law of sines

Sin(pi - Theta - pi/4)/c = sin(pi/4)/r(Theta) where C sits at (c,0)

do some algebra and arrive at

r(Theta) = sqrt(2)*c / (2sin(3pi/4 - Theta)

now we need a constant k such that integrating k*r(Theta) will give you 1, which you can easily do.

I got

a*sin(pi/4)ln|tan((Theta+pi/4)/2)| evaluated from 0 to pi/4

you've successfully build the p.d.f. (probability distribution function) for your r(Theta), now calculate the c.d.f. (cumulative distribution function), set it to uniform and get a closed form expression for your Theta.

up to now we've constructed the random Theta, to build the radius r, realize that much like a circle we have more mass further away and we can construct it as

R = r(Theta)/s where s is uniform from 0 to 1.

we use r(Theta) because it's the max possible value given Theta.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top