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 |
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 |
domain |
object
|
Validated domain object used by the computation. |
mode |
Literal['standard', 'power']
|
|
sites |
ndarray
|
Read-only |
ids |
ndarray
|
Read-only |
cells |
list[dict[str, Any]]
|
Raw user-visible cell dictionaries after external-ID remapping. |
cell_measures |
ndarray
|
Read-only |
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 |
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
|
representation_shift |
float | None
|
Common additive weight shift used to obtain the
backend radii, or |
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
|
required |
ax
|
Axes | None
|
Optional existing matplotlib axes. |
None
|
domain
|
_SupportsPlanarBounds | None
|
Optional planar domain. When it exposes |
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]
|
|
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.
:::