Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

What cubic function can I use to get a random distribution biased towards the middle

I want a circle with more circles inside it (doesn’t strictly need to be inside it). The position of inner circles are determined randomly in a way that there should be most circles at the centre and less and less and it goes out towards the edge of the circle.

From this question, I gathered that numbers can be biased using f(x) instead of just x, x being the random number, of course. Here is the code:

def distBiasedMiddle(_min, _max):
    r = lambda : random.uniform(0, 1)
    r1, r2 = r(), r()
    bias = lambda _r:  _r**3 * (1 + _max - _min) + _min
    return (bias(r1), bias(r2))

testBias = distBiasedMiddle

rps = []
for i in range(100):
    rps.append(testBias(-50, 50))

while True:

    for p in rps:
         pygame.draw.circle(window, (255, 0, 0), (p[0] + 300, p[1] + 300), 2)
    pygame.draw.circle(window, (0,255,0), (300, 300), 50, 1)

For people not familiar with pygame, green circle is of radius 50 and is drawn at (300, 300) and the red circles are drawn at (p[0] + 300, p[1] + 300)

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Here I used x ** 3 but It did not work. I need help picking the correct function. Here’s what I got.

enter image description here

I know that the rest of the code is correct because I used another function mentioned in that answer (f(X)=2X/(1+X)) and it gives the right distribution, biased towards the higher values:

def distBiasedUpper(_min, _max):
    r = lambda : random.uniform(0, 1)
    r1, r2 = r(), r()
    bias = lambda _r: (2 * _r / (1 + _r)) * (1 + _max - _min) + _min
    return (bias(r1), bias(r2))

>Solution :

Actually you are generating random numbers in the range [0.0, 1.0] and assigning them to the range [_min, _max]. Therfore 0 is mapped to _min. As a result, there are more points near _min.
You have to generate random numbers in range [-1.0, 1.0] and map them to the range [_min, _max]. So 0 is in the middle of the range and most of the points are near (_min + _max) / 2:

def distBiasedMiddle(_min, _max):
    r = lambda : random.uniform(-1, 1)
    r1, r2 = r(), r()
    bias = lambda _r:  _r**3 * (_max - _min) / 2 + (_min + _max) / 2
    return (bias(r1), bias(r2))

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading