Skip to content

Shapes and node masks

Download notebookView on GitHubRun when the site was built.

Test points against a shape, select the nodes it covers, and visualize the result.

The simgeometry.objects package includes Line in 1D; Circle, Rectangle, Triangle, Polygon, and apertures in 2D; and Sphere, Cuboid, and apertures in 3D. The same contains(), contains_points(), and node_mask() pattern works across these shapes.

import numpy as np
from simgeometry.grid import Grid
from simgeometry.objects import Circle
grid = Grid(2, (0.0, 0.0), (1.0, 1.0), (41, 41))
circle = Circle(midpoint=(0.5, 0.5), radius=0.25)
mask = circle.node_mask(grid)
indices = circle.get_indices_in_object(grid)
print("mask shape:", mask.shape)
print("selected nodes:", len(indices))
assert indices == grid.indices_from_mask(mask)
mask shape: (41, 41)
selected nodes: 313

node_mask() is a host NumPy boolean array with the grid’s shape. Use get_indices_in_object() when you need integer node indices instead.

points = np.array([[0.5, 0.0, 0.8], [0.5, 0.0, 0.5]])
print("single point:", circle.contains((0.5, 0.5)))
print("point batch:", circle.contains_points(points))
assert circle.contains_points(points).tolist() == [True, False, False]
single point: True
point batch: [ True False False]

Batch points are component-major: the input shape is (ndim, N), with one point per column. To see where the mask lies on the grid, plot its selected nodes.

import matplotlib.pyplot as plt
nodes = grid.node_points()
fig, ax = plt.subplots(figsize=(5, 5))
ax.scatter(nodes[0], nodes[1], c=mask.ravel(), cmap="coolwarm", s=9)
ax.set(xlabel="x", ylabel="y", title="Grid nodes selected by Circle.node_mask")
ax.set_aspect("equal")
plt.show()
Notebook output

Pass inverted=True to select the space outside a shape. The shape’s bounding box still describes its original geometry.

outside = Circle(midpoint=(0.5, 0.5), radius=0.25, inverted=True)
print("center selected:", outside.contains((0.5, 0.5)))
print("corner selected:", outside.contains((0.0, 0.0)))
assert np.array_equal(outside.node_mask(grid), ~mask)
center selected: False
corner selected: True