Skip to content
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 Distribution access methods for ShapeSample trait #13315

Merged
merged 1 commit into from May 22, 2024

Conversation

mweatherley
Copy link
Contributor

@mweatherley mweatherley commented May 10, 2024

Stolen from #12835.

Objective

Sometimes you want to sample a whole bunch of points from a shape instead of just one. You can write your own loop to do this, but it's really more idiomatic to use a rand Distribution with the sample_iter method. Distributions also support other useful things like mapping, and they are suitable as generic items for consumption by other APIs.

Solution

ShapeSample has been given two new automatic trait methods, interior_dist and boundary_dist. They both have similar signatures (recall that Output is the output type for ShapeSample):

fn interior_dist(self) -> impl Distribution<Self::Output>
where Self: Sized { //... }

These have default implementations which are powered by wrapper structs InteriorOf and BoundaryOf that actually implement Distribution — the implementations effectively just call ShapeSample::sample_interior and ShapeSample::sample_boundary on the contained type.

The upshot is that this allows iteration as follows:

// Get an iterator over boundary points of a rectangle:
let rectangle = Rectangle::new(1.0, 2.0);
let boundary_iter = rectangle.boundary_dist().sample_iter(rng);
// Collect a bunch of boundary points at once:
let boundary_pts: Vec<Vec2> = boundary_iter.take(1000).collect();

Alternatively, you can use InteriorOf/BoundaryOf explicitly to similar effect:

let boundary_pts: Vec<Vec2> = BoundaryOf(rectangle).sample_iter(rng).take(1000).collect();

Changelog

  • Added InteriorOf and BoundaryOf distribution wrapper structs in bevy_math::sampling::shape_sampling.
  • Added interior_dist and boundary_dist automatic trait methods to ShapeSample.
  • Made shape_sampling module public with explanatory documentation.

Discussion

Design choices

The main point of interest here is just the choice of impl Distribution instead of explicitly using InteriorOf/BoundaryOf return types for interior_dist and boundary_dist. The reason for this choice is that it allows future optimizations for repeated sampling — for example, instead of just wrapping the base type, interior_dist/boundary_dist could construct auxiliary data that is held over between sampling operations.

@NthTensor NthTensor added C-Enhancement A new feature A-Math Fundamental domain-agnostic mathematical operations labels May 13, 2024
@alice-i-cecile alice-i-cecile added the C-Needs-Release-Note Work that should be called out in the blog due to impact label May 22, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue May 22, 2024
@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label May 22, 2024
Merged via the queue into bevyengine:main with commit d2ef88f May 22, 2024
32 checks passed
@mweatherley mweatherley deleted the sampling-docs branch May 22, 2024 14:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Math Fundamental domain-agnostic mathematical operations C-Enhancement A new feature C-Needs-Release-Note Work that should be called out in the blog due to impact S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants