diff --git a/docs/attachments/animation.gif b/docs/attachments/animation.gif new file mode 100644 index 0000000..df89fe9 Binary files /dev/null and b/docs/attachments/animation.gif differ diff --git a/docs/attachments/example.png b/docs/attachments/example.png new file mode 100644 index 0000000..f98fbb2 Binary files /dev/null and b/docs/attachments/example.png differ diff --git a/docs/attachments/tree.gif b/docs/attachments/tree.gif new file mode 100644 index 0000000..4704d2b Binary files /dev/null and b/docs/attachments/tree.gif differ diff --git a/docs/index.rst b/docs/index.rst index f1a7cd3..654e468 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,8 +3,8 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Welcome to Foronoi's documentation! -=================================== +Foronoi +======= Foronoi is a Python implementation of the Fortune's algorithm based on the description of "Computational Geometry: Algorithms and Applications" by de Berg et al. @@ -35,7 +35,9 @@ Table of contents :maxdepth: 2 :glob: - installation + self + pages/installation + pages/quickstart api private observers diff --git a/docs/installation.rst b/docs/pages/installation.rst similarity index 92% rename from docs/installation.rst rename to docs/pages/installation.rst index e0a4ea6..f1af860 100644 --- a/docs/installation.rst +++ b/docs/pages/installation.rst @@ -1,5 +1,5 @@ Installation -=================== +============ Via pip +++++++ diff --git a/docs/pages/quickstart.rst b/docs/pages/quickstart.rst new file mode 100644 index 0000000..4376a5a --- /dev/null +++ b/docs/pages/quickstart.rst @@ -0,0 +1,155 @@ +Quick start +=========== + +Basic example +------------- +This is a basic example that quickly constructs and visualizes a voronoi graph. + +.. code-block:: python + + from foronoi import Voronoi, Polygon, Visualizer, Point, VoronoiObserver + from foronoi.graph import HalfEdge, Vertex + + # Define some points (a.k.a sites or cell points) + points = [ + (2.5, 2.5), (4, 7.5), (7.5, 2.5), (6, 7.5), (4, 4), (3, 3), (6, 3) + ] + + # Define a bounding box / polygon + polygon = Polygon([ + (2.5, 10), (5, 10), (10, 5), (10, 2.5), (5, 0), (2.5, 0), (0, 2.5), (0, 5) + ]) + + # Initialize the algorithm + v = Voronoi(polygon) + + # Optional: visualize the voronoi diagram at every step. + # You can find more information in the observers.py example file + # v.attach_observer( + # VoronoiObserver() + # ) + + # Create the Voronoi diagram + v.create_diagram(points=points) + + # Visualize the Voronoi diagram + Visualizer(v) \ + .plot_sites(show_labels=False) \ + .plot_edges(show_labels=False) \ + .plot_vertices() \ + .show() + +Result: + +.. image:: ../attachments/example.png + :width: 800 + :alt: Voronoi diagram result + +Properties +---------- + +Below are some examples of how to retrieve certain components and properties from the voronoi graph and what +kind of operations are possible. + +.. code-block:: python + + from typing import List + + # Some examples of how to access properties from the Voronoi diagram: + edges: List[HalfEdge] = v.edges # A list of all edges + vertices: List[Vertex] = v.vertices # A list of all vertices + sites: List[Point] = v.sites # A list of all cell points (a.k.a. sites) + + edge, vertex, site = edges[0], vertices[0], sites[0] + + # Edge operations + origin: Vertex = edge.origin # The vertex in which the edge originates + target: Vertex = edge.twin.origin # The twin is the edge that goes in the other direction + target_alt: Vertex = edge.target # Same as above, but more convenient + twin: HalfEdge = edge.twin # Get the twin of this edge + next_edge: HalfEdge = edge.next # Get the next edge + prev_edge: HalfEdge = edge.twin.next # Get the previous edge + prev_alt: HalfEdge = edge.prev # Same as above, but more convenient + + # Site operations + size: float = site.area() # The area of the cell + borders: List[HalfEdge] = site.borders() # A list of all the borders that surround this cell point + vertices: List[Vertex] = site.vertices() # A list of all the vertices around this cell point + site_x: float = site.x # X-coordinate of the site + site_xy: [float, float] = site.xy # (x, y)-coordinates of the site + first_edge: HalfEdge = site.first_edge # Points to the first edge that is part of the border around the site + + # Vertex operations + connected_edges: List[HalfEdge] = vertex.connected_edges # A list of all edges that are connected to this vertex + vertex_x: float = vertex.x # x-coordinate of the vertex + vertex_xy: [float, float] = vertex.xy # (x, y)-coordinates of the vertex + +Observers +--------- + +Observers allow you to observe the state of the algorithm and visualize components during the construction of the +voronoi graph. Below you can see an example where we attach an observer that visualizes the voronoi graph at every +step (event). + +.. code-block:: python + + import os + + from foronoi import Polygon, Voronoi, VoronoiObserver + from foronoi.visualization import Presets + + # Define some points (a.k.a sites or cell points) + points = [ + (2.5, 2.5), (4, 7.5), (7.5, 2.5), (6, 7.5), (4, 4), (3, 3), (6, 3) + ] + + # Define a bounding box / polygon + polygon = Polygon([ + (2.5, 10), (5, 10), (10, 5), (10, 2.5), (5, 0), (2.5, 0), (0, 2.5), (0, 5) + ]) + + # Initialize the algorithm + v = Voronoi(polygon) + + # Attach a Voronoi observer that visualizes the Voronoi diagram every step + v.attach_observer( + VoronoiObserver( + + # Settings to pass into the visualizer's plot_all() method. + # - By default, the observer uses a set of minimalistic presets + # that are useful for visualizing during construction, clipping + # and the final result. + # - The settings below will update the default presets used by the + # observer. For example, by default, the arc_labels are not shown, + # but below we can enable the arc labels. Other parameters can be + # found in the visualizer's plot_all() method. + settings=dict(arc_labels=True, site_labels=True), + + # Callback that saves the figure every step + # If no callback is provided, it will simply display the figure in + # a matplotlib window + callback=lambda observer, figure: figure.savefig( + f"output/voronoi/{observer.n_messages:02d}.png" + ), + + visualize_steps=True # Default = True + visualize_before_clipping=True # Default = False + visualize_result=True # Default = True + ) + ) + + # Create the output directory if it doesn't exist + if not os.path.exists("output"): + os.mkdir("output") + + if not os.path.exists("output/voronoi/"): + os.mkdir("output/voronoi/") + + # Create the Voronoi diagram + v.create_diagram(points=points) + +Slideshow of images in `output/voronoi/`: + +.. image:: ../attachments/animation.gif + :width: 800 + :alt: Voronoi diagram construction animation diff --git a/docs/private.rst b/docs/private.rst index b35de1c..32a7848 100644 --- a/docs/private.rst +++ b/docs/private.rst @@ -7,3 +7,5 @@ Private classes :glob: private/* + +**Note:** More to be added soon! diff --git a/examples/check.py b/examples/check.py new file mode 100644 index 0000000..0571cd9 --- /dev/null +++ b/examples/check.py @@ -0,0 +1,31 @@ +from foronoi import Voronoi, Polygon, Visualizer, Point, VoronoiObserver +from foronoi.graph import HalfEdge, Vertex + +# Define some points (a.k.a sites or cell points) +points = [ + (2.5, 2.5), (4, 7.5), (7.5, 2.5), (6, 7.5), (4, 4), (3, 3), (6, 3) +] + +# Define a bounding box / polygon +polygon = Polygon([ + (2.5, 10), (5, 10), (10, 5), (10, 2.5), (5, 0), (2.5, 0), (0, 2.5), (0, 5) +]) + +# Initialize the algorithm +v = Voronoi(polygon) + +# Optional: visualize the voronoi diagram at every step. +# You can find more information in the observers.py example file +# v.attach_observer( +# VoronoiObserver() +# ) + +# Create the Voronoi diagram +v.create_diagram(points=points) + +# Visualize the Voronoi diagram +Visualizer(v) \ + .plot_sites(show_labels=False) \ + .plot_edges(show_labels=False) \ + .plot_vertices() \ + .show() \ No newline at end of file