petosegan / rust_voronoi

Rust implementation of Fortune's algorithm for generating Voronoi diagrams
MIT License
25 stars 19 forks source link

Create a ``VoronoiDiagram`` struct that wraps the DCEL for Voronoi specific behaviour? #3

Open kaedroho opened 6 years ago

kaedroho commented 6 years ago

I think it would be nice to create a VoronoiDiagram struct which provides a place to put Voronoi-specific features (for example: make_polys) while keeping DCEL generic. We could also implement logic for linking cells to the points list and excluding the border cell here too.

Idea for API:

(note: I used the impl syntax for brevity, actual implementation would use concrete types so it works on stable Rust)

struct VoronoiDiagram {
    /// DCEL is public allowing low-level access
    pub dcel: DCEL
}

impl VoronoiDiagram {
    /// Returns an iterator of the cells in the diagram
    pub fn cells(&self) -> impl Iterator<Item=VoronoiCell>;

    /// Returns an iterator over line segments in the diagram
    pub fn segments(&self) -> impl Iterator<Item=(Point, Point)>;

    /// Returns an iterator over Voronoi points in the diagram (excluding border points?)
    pub fn points(&self) -> impl Iterator<Item=Point>;
}

struct VoronoiCell {
    /// No public attributes
}

impl VoronoiCell {
    /// Returns the index of the point in the original points array that this cell was generated from
    pub fn index(&self) -> usize;

    /// Computes the centroid of the cell
    pub fn centroid(&self) -> Point;

    /// Returns an iterator of the points that border the cell
    pub fn points(&self) -> impl Iterator<Item=Point>;
}

The voronoi function would be changed to return a VoronoiDiagram instead of the DCEL.

Let me know if you have any thoughts.

petosegan commented 6 years ago

This looks reasonable to me. I expect that a lot of applications would want to use the underlying DCEL to get adjacency information, but this seems very useful for simple applications and plotting.

I think there is probably an efficient way to compute the Voronoi-cell-to-original-point mapping during construction of the DCEL, but I haven't thought it through.

Somewhat related: probably the boundary cropping shouldn't be happening in the voronoi method, and should instead be a method on VoronoiDiagram. This would mean that the DCEL needs to be extended to represent half-infinite edges. The main difficulty I see with this is that then you can't just remove points outside the boundaries before computing the Voronoi diagram, so the boundary cropping algorithm gets more complicated.