pythonarcade / arcade

Easy to use Python library for creating 2D arcade games.
http://arcade.academy
Other
1.71k stars 330 forks source link

Check distribution of arcade.math.rand_* functions #2428

Open pushfoo opened 1 month ago

pushfoo commented 1 month ago

Enhancement request:

TL;DR: Check for more random call centering bias like that of #2425

What needs verification

In #2426, a call to math.sqrt to wrap the random call seems to fix an issue with center-clustering bias in rand_in_circle. It seems reasonable to check for & fix any similar bias in:

What would it help with?

Evenness of randomized points.

Best approach?

I'm open to suggestions on this. These seem like hot code paths so I'm uncertain of OOP-y abstractions / indirection layers to customize which distribution function we're mapping into. Thoughts welcome.

pushfoo commented 1 month ago

@Rapen765 Are you up for taking a look at this?

Rapen765 commented 1 month ago

Yes, I am currently checking the functions and I am sure that those are correct: rand_on_line - the output is a line so a linear random function is good rand_on_circle - the output is also a line but not straight, but still the function is good rand_angle_360_deg - this is just a random value from 0 to 360 rand_magnitude - this is just like rand_on_line but instead of two points there is an angle and two magnitudes rand_angle_spread_deg - this is just like rand_angle_360_deg but instead of the fixed angle you can change it rand_vec_spread_deg - this is the rand_angle_spread_deg but converted to vector the rand_in_rect function is also correct.

Rapen765 commented 1 month ago

The only problem is the function rand_on_line documentation

def rand_on_circle(center: Point2, radius: float) -> Point2: """ Generate a point on a circle.

.. note: by passing a random value in for float,
         you can achieve what rand_in_circle() does

Args:
    center (Point2): The center of the circle
    radius (float): The radius of the circle
"""
angle = 2 * math.pi * random.random()
return (radius * math.cos(angle) + center[0], radius * math.sin(angle) + center[1])

the note is now incorrect because you would have to pass a sqrt(random()) and not random(). Also not in for float but for radius.

pushfoo commented 1 month ago

While we wait for feedback from Dragon on the tuple vs Vec2 perf issues, would you be up for adding this doc change to #2430?