Skip to content

Instantly share code, notes, and snippets.

@isedgar
Last active September 18, 2023 21:07
Show Gist options
  • Save isedgar/adbf6b035f8cce62e87998a825ba4294 to your computer and use it in GitHub Desktop.
Save isedgar/adbf6b035f8cce62e87998a825ba4294 to your computer and use it in GitHub Desktop.
Naive pseudocode to create Voronoi cells (long version).

Voronoi diagram in the Cartesian plane

INPUT:

sites := {(x0, y0), (x1, y1), ..., (xn-1, yn-1)}

pad := padding (some number)


ALGORITHM:

n := number of sites

xl := minimum x-coordinate in sites (left)
xr := maximum x-coordinate in sites (right)
yt := maximum y-coordinate in sites (top)
yb := minimum y-coordinate in sites (bottom)

Box := {(xl-pad,yt+pad), (xr+pad,yt+pad), (xr+pad,yb-pad), (xl-pad,yb-pad)}

cells := {}

for each i in {0, 1, ..., n-1} do:
    cell := Box

    site := sites[i]

    for each j in {0, 1, ..., n-1} do:
        if i = j, continue with next iteration

        m := length(cell)  *number of vertices in cell*

        new_cell := {}

        next := sites[j]

        bisector := two_points_bisector(site, next)   *perpendicular bisector of site and next*

        for each k in {0, 1, ..., m-1} do:
            A := cell[k]
            B := cell[(k+1) mod m]

            egde := segment(A, B)

            if bisector intersects edge, then:
                t := intersection(edge, bisector)

                if t = B, then:
                    new_cell := {B, cell[(k+2) mod m]}

                    first_intersection_index := (k+2) mod m

                otherwise:
                    new_cell := {t, B}

                    first_intersection_index := (k+1) mod m

                finish loop


        if new_cell = {}, then:
            new_cell := cell

        otherwise:
            for each k in {first_intersection_index, first_intersection_index+1, ..., m-1} do:
                A := cell[k]
                B := cell[(k+1) mod m]

                egde := segment(A, B)

                if bisector intersects edge, then:
                    u := intersection(edge, bisector)

                    new_cell ∪ {u}  *add u to new_cell*

                    second_intersection_index := k+1;

                    finish loop

                otherwise:
                    new_cell ∪ {B}  *add B to new_cell*


            if site is not in new_cell, then:
                new_cell := {u}

                while second_intersection_index mod m ≠ first_intersection_index do:
                    v := cell[second_intersection_index mod m]

                    new_cell ∪ {v}  *add v to new_cell*

                    second_intersection_index := second_intersection_index + 1

                new_cell ∪ {t}  *add t to new_cell*

        cell = new_cell

    cells ∪ {cell}  *add cell to cells*

OUTPUT:

cells

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment