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

[WIP] Uniform polygon sampling #129

Closed
wants to merge 8 commits into from

Conversation

OwenGraves
Copy link

I'd like to implement uniform polygon sampling. I've added uniform triangle sampling, but am still working on the other methods.

Any and all feedback, criticism, or best practices information would be much appreciated! 😄

@lemmih
Copy link
Collaborator

lemmih commented Mar 6, 2021

Nice!
You can split a polygon into triangles by using the triangulation module and this code snippet:

import Algorithms.Geometry.PolygonTriangulation.Triangulate

polygonTriangles :: (Ord r, Fractional r) => Polygon t p r -> [SimplePolygon p r]
polygonTriangles p =
    map (view core) $
    map (`rawFacePolygon` g) $
    map fst $ V.toList (internalFaces g)
  where
    g = triangulate' Proxy p

sampleTriangle (Triangle v1 v2 v3) = do
a' <- getRandomR (0, 1)
b' <- getRandomR (0, 1)
let (a, b) = if a' + b' > 1 then (1 - a', 1 - b') else (a', b') in
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can drop the in part of the let-expression and keep the return on the same level of indentation.

@OwenGraves
Copy link
Author

Not sure if the animation is in the right place (or setting files modified correctly) and the animation could be beautified, but it seems to work!

@noinia
Copy link
Owner

noinia commented Mar 8, 2021

Does this strategy of sampling triangles really produce a uniform sampling? Intuitively it seems similar to sampling in a disk by taking an uniform sample of polar coordinates. However that does not produce an uniform sampling in the disk, as you are more likely to pick points near the center this way. This type of sampling seems very similar to that, so I would like to see more evidence that this produces the right result.

A simple alternative strategy is to simply sample uniformly at random from the boundingbox of the triangle and resample if it turns out that point does not lie in the triangle (but that is a bit slower/may require more random bits).

@lemmih
Copy link
Collaborator

lemmih commented Mar 8, 2021

The sampling /is/ uniform. We use the triangle to create a parallelogram which can be sampled uniformly. A sampled point has a 50% chance of being outside of the original triangle. If the point is outside, we reflect it over the triangle edge such that it ends up inside the triangle. Thus we have uniform sampling in O(1) steps.

This article describes the approach in detail: https://blogs.sas.com/content/iml/2020/10/19/random-points-in-triangle.html

@lemmih
Copy link
Collaborator

lemmih commented Mar 8, 2021

I'll document the algorithm before merging this PR.

@lemmih
Copy link
Collaborator

lemmih commented Mar 16, 2021

Hi @OwenGraves,
I've modified your animation to use text polygons:

uniformsampling.mp4

There are still a few TODO items left but I think we can handle those in another PR and merge this one.

@lemmih
Copy link
Collaborator

lemmih commented Mar 16, 2021

TODO items:

  • O(log n) sampling using a fingertree.
  • Uniform sampling of multiple polygons at once.
  • Drop the Real r constraint (by not using fromList).

@lemmih
Copy link
Collaborator

lemmih commented Mar 16, 2021

On the website: https://hgeometry.org/#uniformsampling

@OwenGraves
Copy link
Author

Awesome, that animation looks really cool!

@OwenGraves
Copy link
Author

Another TODO item could be to implement the Alias method since it looks like it might be a way to do this sampling in O(1) after the initial setup.

noinia added a commit that referenced this pull request Aug 16, 2024
* sampling polygons

* sampling polygons

* some additional documentation

* some cleaning up of the imports

* no longer load semigroupids?
@noinia
Copy link
Owner

noinia commented Aug 16, 2024

I've ported these results to the new hgeometry version in #238 , so I'm closing this one :).

@noinia noinia closed this Aug 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants