-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Vector2
circle points generation method to RandomNumberGenerator
#43103
Conversation
Large asteroid belts coming as soon as this lands <3 <3 <3 |
core/math/random_number_generator.h
Outdated
return Vector2(r * Math::cos(t), r * Math::sin(t)); | ||
} | ||
|
||
_FORCE_INLINE_ Vector2 randv_range_circle(real_t p_min_radius = 0.0, real_t p_max_radius = 1.0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Subjectively, I think randv_range_circle
should be named randv_circle_range
(to filter it better alphabetically) or even randv_ring
(radically)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like randv_ring
, and perhaps range
is not the best choice here because it might falsely suggest that it's going to generate arc/sector range rather than radius range. That said, going for consistency with existing *_range
methods could actually hurt the meaning.
Except that if we rename randv_range_circle
to randv_ring
, if you have min_radius == max_radius
, then it's not really a ring anymore, but restricted to circle's boundary, there's a reason why godotengine/godot-proposals#1731 lists rand_point_on_circle
to handle this case, both in terms of use cases and effeciency.
That way, randv_circle_range
and randv_ring_range
could be added later to restrict the generation to a sector, but that's likely overkill for Godot, and I'm not sure how trivial it is to implement it. But then again, randv_circle_sector
and randv_ring_sector
would probably make more sense anyways (mostly talking about extending RandomNumberGenerator
via modules now).
That said, there are many different ways to name this, I'm fine with either (but prefer less verbose names myself).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed randv_range_circle
→ randv_ring
for now. 🙂
Apart from So, to list all the proposed methods:
Again, refer to Unity Random API. The implementation is superior to Unity because this PR allows you to override unit circle and specify different radius, but it does generate points in unit circles by default. 😉 And by the way, var rng = RandomNumberGenerator.new()
$Sprite.rotation = rng.randv_on_circle().angle() |
randv_circle
and randv_range_circle
to RandomNumberGenerator
Vector2
circle generation methods to RandomNumberGenerator
I can also remove So, alternatively, the current With:
At expense of performance for simple use cases, of course. |
Or maybe it's better to be like Unity (https://docs.unity3d.com/ScriptReference/Random.html) where you generate a unit vector and the user should manually multiply it by a scalar to provide a required radius for a circle or a sphere. |
Performance is not priority for Godot development as seen in best practices, so I'd prefer to have general-purpose solution if we go this route. The default range can be set to I'm also not sure whether limited floating point precision could allow high enough granularity, what I mean is that if you generate thousands of points within the unit length and multiply by scalar, then you may suffer from bad distribution within an area, also given the default Godot's floating point epsilon: #define CMP_EPSILON 0.00001 |
Vector2
circle generation methods to RandomNumberGenerator
Vector2
circle points generation methods to RandomNumberGenerator
I agree with Chaosus here, there is not need to provide a range version of the function here. |
Applied suggested changes, only |
Vector2
circle points generation methods to RandomNumberGenerator
Vector2
circle points generation method to RandomNumberGenerator
See alternative PR which should be simpler to maintain, and which won't bloat Godot's binary sizes much: #43343. |
I've closed #43343 for the reasons outlined in #43343 (comment). I'm going to assume that groud is going to say that this PR should be more feature-complete when comparing to #43343, similarly to rationale slightly unrelated to this PR #48237 (comment):
Nonetheless, this PR also allows to provide minimum and maximum radiuses similarly (instead of having to multiply by vector via script), which also doesn't suffer from uniformity issues as described in #43343 (comment), so this should be feature-complete. |
Well, no. My opinion is that they are different APIs that should be considered differently. Here, I believe that a random number generator should provide very basic elements only to build upon, as it's easy to go feature creep in that kind of areas. There are plenty of ways to generate random things. Like you may want to generate the direction uniformly, but the length with a normal distribution. As a consequence, I'd rather keep the API simple, with a simple For the Vector2 API, my reasoning is different, as I believe that |
You can also say that this PR is a feature creep as well, since So, that's why I'm assuming you'd rather prefer a more feature-complete solution here, because otherwise you'd already reject the idea in the first place. Or have you changed your opinion in the meantime? To clarify, it's not my task to point to contradictions for the sake of it, I'd just like to better understand your current opinion on this based on previous (even marginally related) discussions, and I'm sorry if it looks rude when I quote stuff.
Again, all these things are currently possible to achieve with this PR, either via script or completely relying on Godot's implementation. I recall you've also said that we could also document the scope, that's also how feature-creep can be resolved. That said, I don't see a major problem with those statements. |
Closing as this contributor can no longer update this further. |
Can someone else pick this up instead? |
Here's a GDScript one-liner if anyone is interested: func random_point_on_ring(outer_radius: float, inner_radius := 0.0):
return Vector2.RIGHT.rotated(randf() * TAU) * sqrt(rand_range(pow(1 - (outer_radius - inner_radius) / outer_radius, 2), 1)) * outer_radius |
Updated snippet for Godot 4 (rand_range renamed to randf_range): func random_point_on_ring(outer_radius: float, inner_radius := 0.0):
return Vector2.RIGHT.rotated(randf() * TAU) * sqrt(randf_range(pow(1 - (outer_radius - inner_radius) / outer_radius, 2), 1)) * outer_radius |
In Godot 4 you can use Vector2.from_angle() instead of RIGHT.rotated() and |
Solves the 2D part for godotengine/godot-proposals#1731.
Closes #34301, resolves #28264.
Provides uniform distribution for generating points in a circle (unit on the circle's boundary by default, but any radius can be specified).
Added documentation and unit tests (tests via separate commit).
Test project:
randv_circle.zip
P.S. This is probably the first feature PR with both documentation and unit tests written ever in Godot. 🙂