Skip to content

Planar 2D API

pyvoro2.planar

Planar 2D namespace for pyvoro2.

Box dataclass

Axis-aligned non-periodic planar box.

from_points(points, padding=2.0) classmethod

Create a bounding box that encloses planar points.

DuplicateError

Bases: ValueError

Raised when near-duplicate points are detected.

NormalizationError

Bases: ValueError

Raised when strict planar normalization validation fails.

NormalizedTopology dataclass

Result of :func:normalize_topology for planar tessellations.

Attributes:

Name Type Description
global_vertices ndarray

Unique planar vertices in Cartesian coordinates.

global_edges list[dict[str, Any]]

Unique geometric edges. Each edge dict contains: - cells: (cid0, cid1) - cell_shifts: ((0, 0), (sx, sy)) - vertices: (gid0, gid1) - vertex_shifts: ((0, 0), (sx, sy))

cells list[dict[str, Any]]

Per-cell dictionaries including vertex_global_id, vertex_shift, and edge_global_id aligned with local edges.

NormalizedVertices dataclass

Result of :func:normalize_vertices for planar tessellations.

Attributes:

Name Type Description
global_vertices ndarray

Array of unique planar vertices in Cartesian coordinates, remapped into the primary cell for periodic domains.

cells list[dict[str, Any]]

Per-cell dictionaries augmented with: - vertex_global_id: list[int] aligned with local vertices - vertex_shift: list[tuple[int, int]] aligned with local vertices

RectangularCell dataclass

Axis-aligned planar cell with optional x/y periodicity.

This is the honest first public 2D domain scope for pyvoro2.planar. It intentionally does not cover non-orthogonal periodic cells.

lattice_vectors property

Return lattice vectors (a, b) in Cartesian coordinates.

remap_cart(points, *, return_shifts=False, eps=None)

Remap Cartesian points into the primary rectangular domain.

TessellationError

Bases: ValueError

Raised when planar tessellation sanity checks fail.

TessellationResult dataclass

Dimension-neutral structured tessellation data.

TessellationResult records common scientific output without erasing dimension-specific geometry. It is the default return from both public compute functions; callers that deliberately need raw cell dictionaries can select output='cells' explicitly.

Attributes:

Name Type Description
dimension Literal[2, 3]

Explicit spatial dimension, either 2 or 3.

domain object

Validated domain object used by the computation.

mode Literal['standard', 'power']

"standard" for a Voronoi diagram or "power" for a power/Laguerre diagram.

sites ndarray

Read-only (n, dimension) copy of validated input coordinates in original input order.

ids ndarray

Read-only (n,) integer IDs in original input order. Omitted external IDs are represented by 0..n-1.

cells list[dict[str, Any]]

Raw user-visible cell dictionaries after external-ID remapping.

cell_measures ndarray

Read-only (n,) snapshot of input-aligned areas in 2D or volumes in 3D. Hidden cells have measure zero.

empty_mask ndarray

Read-only input-aligned boolean snapshot. It includes empty cells even when their raw records were omitted.

input_weights ndarray | None

Read-only copy of mathematical power weights when the caller supplied weights=; otherwise None.

backend_radii ndarray | None

Read-only copy of the exact non-negative radii supplied to the native power backend; for weight-first input these equal sqrt(input_weights + representation_shift). None in standard mode.

representation_shift float | None

Common additive weight shift used to obtain the backend radii, or None for standard mode and direct radii.

tessellation_diagnostics object | None

Dimension-specific tessellation diagnostics, when computed.

normalized_vertices object | None

Dimension-specific normalized-vertex output, when computed.

normalized_topology object | None

Dimension-specific normalized-topology output, when computed.

The outer object is frozen and every aligned numeric array is an owned, read-only copy. cells is deliberately different: the exact supplied list is retained, and its dictionaries and nested geometry remain mutable. The measure and empty-mask arrays are construction-time snapshots and do not follow later raw-record mutation. Mutating boundary records does affect later boundary access and may make :meth:require_boundaries raise an inconsistency error. Normalization and diagnostic objects retain their own dimension-specific mutability contracts.

Direct construction is provisional. The constructor validates raw-cell IDs, measures, empty state, representation metadata, and capability metadata against the aligned fields rather than repairing inconsistent input. The private keyword-only _boundaries_available and _periodic_shifts_available parameters carry construction capability state; the shared builder supplies them for normal integration use. Deep copies and pickle round trips preserve the existing snapshot state while restoring read-only owned arrays and capability state, even after allowed raw-record mutation.

boundary_kind property

Dimension-specific raw-cell boundary key.

global_edges property

Global planar edges when topology normalization is available.

global_vertices property

Global planar vertices from the available normalized output.

This provisional convenience preserves the historical PlanarComputeResult access pattern. It is None when no planar normalization output is available.

has_boundaries property

Whether raw boundary geometry was available to the builder.

has_normalized_topology property

Whether dimension-specific topology normalization is present.

has_normalized_vertices property

Whether dimension-specific vertex normalization is present.

has_periodic_shifts property

Whether boundary records carry requested periodic image shifts.

has_tessellation_diagnostics property

Whether dimension-specific tessellation diagnostics are present.

measure_kind property

Dimension-specific name of the values in cell_measures.

__deepcopy__(memo)

Deep-copy snapshots and mutable contents without revalidation.

__post_init__()

Validate the common contract and take ownership of aligned arrays.

__reduce_ex__(protocol)

Use a version-independent pickle restoration path.

require_boundaries()

Return boundary collections aligned with original input order.

Hidden sites always have empty boundary collections, whether their raw records were omitted or contain an explicitly empty collection. When :attr:has_periodic_shifts is true, returned edge or face records contain adjacent_shift annotations.

Raises:

Type Description
ValueError

If boundary geometry was not available, or if later mutation made the shared raw records internally inconsistent.

require_normalized_topology()

Return normalized topology or raise if none was computed.

require_normalized_vertices()

Return normalized vertices or raise if none were computed.

require_tessellation_diagnostics()

Return tessellation diagnostics or raise if none were computed.

analyze_tessellation(cells, domain, *, expected_ids=None, mode=None, area_tol_rel=1e-08, area_tol_abs=1e-12, check_reciprocity=True, check_line_mismatch=True, line_offset_tol=None, line_angle_tol=None, mark_edges=True)

Analyze planar tessellation sanity and optionally annotate edges.

annotate_edge_properties(cells, domain, *, tol=1e-12)

Annotate 2D edges with basic geometric descriptors in-place.

Added edge fields (when computable): - midpoint: [x, y] - tangent: [tx, ty] unit tangent from vertex[0] -> vertex[1] - normal: [nx, ny] unit normal oriented from site -> edge - length: float - other_site: [x, y] if the neighboring site can be resolved

compute(points, *, domain, ids=None, duplicate_check='off', duplicate_threshold=1e-05, duplicate_wrap=True, duplicate_max_pairs=10, block_size=None, blocks=None, init_mem=8, mode='standard', weights=None, radii=None, return_vertices=True, return_adjacency=True, return_edges=True, return_edge_shifts=False, edge_shift_search=2, include_empty=False, validate_edge_shifts=True, repair_edge_shifts=False, edge_shift_tol=None, return_diagnostics=False, output=_DEFAULT_OUTPUT, return_result=None, normalize='none', normalization_tol=None, tessellation_check='none', tessellation_require_reciprocity=None, tessellation_area_tol_rel=1e-08, tessellation_area_tol_abs=1e-12, tessellation_line_offset_tol=None, tessellation_line_angle_tol=None)

Compute planar Voronoi or power tessellation cells.

Supported domains
  • :class:~pyvoro2.planar.domains.Box
  • :class:~pyvoro2.planar.domains.RectangularCell

By default, planar compute returns one :class:~pyvoro2.TessellationResult. Set output="cells" for the explicit raw cell list, or (cells, diagnostics) when return_diagnostics=True. Structured results always carry computed diagnostics inside result.tessellation_diagnostics and never return a tuple.

Wrapper-level normalization convenience is also available via normalize='vertices' or 'topology'. Any request for normalized output returns a :class:~pyvoro2.TessellationResult. return_result= remains as a deprecated compatibility selector; its default None means that no legacy selection was supplied. Passing True or False emits :class:DeprecationWarning; use output= in new code. The normalized structures intentionally carry their own augmented cell copies, so the raw cells field can stay lightweight even when internal geometry was needed for diagnostics or normalization.

For periodic domains, diagnostics and normalization automatically compute temporary edge shifts and the required edge/vertex geometry internally, even when those fields were not requested by the caller. Any such temporary fields are stripped from the raw returned cells unless they were explicitly requested.

In mode='power', supply exactly one of weights or radii. Mathematical weights follow the power convention ||x - p_i||^2 - w_i and have squared-length units; positive, zero, and negative finite weights are valid when the common-shift conversion remains finite and representable. Non-finite input or overflow during conversion raises ValueError before native computation. Finite representability does not guarantee a numerically resolvable native tessellation. Voro++ evaluates radical geometry with binary64 squared-radius arithmetic, so very large absolute radii**2 values or genuine weight ranges relative to squared coordinate/domain scales can lose geometric resolution. There is no universal safe cutoff: the onset depends on scale, geometry, platform, and compiler, and periodic power tessellations are a particularly sensitive regime. pyvoro2 converts valid weights to non-negative backend radii with one common global shift, so adding the same constant to every weight does not change the diagram. Radii have length units and are a non-unique backend representation, not necessarily physical radii. Standard mode rejects both weights and radii because neither representation has meaning there.

duplicate_check(points, *, threshold=1e-05, domain=None, wrap=True, mode='raise', max_pairs=10)

Detect planar point pairs closer than an absolute threshold.

ghost_cells(points, queries, *, domain, ids=None, duplicate_check='off', duplicate_threshold=1e-05, duplicate_wrap=True, duplicate_max_pairs=10, block_size=None, blocks=None, init_mem=8, mode='standard', radii=None, ghost_radius=None, return_vertices=True, return_adjacency=True, return_edges=True, return_edge_shifts=False, edge_shift_search=2, include_empty=True, validate_edge_shifts=True, repair_edge_shifts=False, edge_shift_tol=None)

Compute ghost Voronoi/Laguerre cells at planar query points.

locate(points, queries, *, domain, ids=None, duplicate_check='off', duplicate_threshold=1e-05, duplicate_wrap=True, duplicate_max_pairs=10, block_size=None, blocks=None, init_mem=8, mode='standard', radii=None, return_owner_position=False)

Locate the owning generator for each planar query point.

normalize_edges(nv, *, domain, tol=None, copy_cells=True)

Build a global edge pool based on an existing planar normalization.

normalize_topology(cells, *, domain, tol=None, require_edge_shifts=True, copy_cells=True)

Convenience wrapper: normalize vertices, then deduplicate edges.

normalize_vertices(cells, *, domain, tol=None, require_edge_shifts=True, copy_cells=True)

Build a global planar vertex pool and per-cell vertex mappings.

plot_tessellation(cells, *, ax=None, domain=None, show_sites=False, annotate_ids=False)

Plot planar cells using matplotlib.

Parameters:

Name Type Description Default
cells Iterable[dict]

Iterable of raw 2D cell dictionaries as returned by pyvoro2.planar.compute or pyvoro2.planar.ghost_cells.

required
ax Axes | None

Optional existing matplotlib axes.

None
domain _SupportsPlanarBounds | None

Optional planar domain. When it exposes bounds, the domain rectangle is drawn as a simple outline.

None
show_sites bool

If True, draw the reported cell sites.

False
annotate_ids bool

If True, label cell IDs at their reported sites.

False

Returns:

Type Description
tuple[Figure, Axes]

(fig, ax).

validate_normalized_topology(normalized, domain, *, level='basic', check_vertex_edge_shift=True, check_edge_vertex_sets=True, check_incidence=True, check_polygon=True, max_examples=10)

Validate periodic shift and topology consistency after normalization.

validate_tessellation(cells, domain, *, expected_ids=None, mode=None, level='basic', require_reciprocity=None, area_tol_rel=1e-08, area_tol_abs=1e-12, line_offset_tol=None, line_angle_tol=None, mark_edges=None)

Validate planar tessellation sanity, optionally raising in strict mode.

:::