Implement uniform random point in polygon, triangle and circle #83
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I've created a couple of sketches using the
g/random-point-inside
sampling method fromISample
, and found it to be very useful, so thank you for providing that functionality.Unfortunately I discovered some limitations. Firstly, the method was not implemented on polygons, or rectangles that had been rotated (which upscales to a polygon). In the process of addressing that, I discovered that the implementation for triangles is biased towards the centroid and not distributed uniformly throughout. Finally, I determined that the method for circle is also biased towards the centroid and not uniform.
The screenshot below is generated using the additional example script
examples/svg/uniform_distribution.clj
and helps demonstrate the bias visually. The clumping bias is quite visible on both the circle and triangle examples.The first column shows distributions generated using the existing
g/random-point-inside
routines. The second column shows all the functionality using the uniform methods. Lastly the final two columns demonstrate both thesample-uniform
andg/random-point
on hull methods appear to be functioning uniformly.The algorithm for polygons involves tessellating into triangles, and then sampling the triangles weighted by area. I suspect the math routines added for weighted probability distributions belong in
thi.ng.math.core
, but wanted to include them here in the interest of a single PR to merge. If this is accepted, I am happy to create the PR necessary to migrate it into the other project.I think my preference would be to replace the
random-point-inside
implementations to use the uniform algorithms, however, that may break existing works generated using these methods. I have tried to think of an alternate name likerandom-point-inside-uniform
to add to the interface, but have not been particularly happy with any names I have thought of. Adding a new interface seems like it would allow a common access method without dropping backwards compatibility but requires a good name. In the interest of sharing the results back with the community I elected to just add each as a helper method, but re-use therandom-point-inside
interface for polygons as no existing functionality can depend on it biasing in a particular way.One last note,
random-point-inside-triangle2
has only been tested on 2d triangles but should work fine in 3d, as the bias weights should work on vec3's just as well as vec2's.Hopefully this functionality is useful for others! Thanks again for this great project.