Source code for brainrender.actors.ruler
"""Ruler actors for measuring distances in brainrender scenes."""
import numpy as np
import numpy.typing as npt
from loguru import logger
from vedo import merge
from vedo.shapes import Line, Sphere, Text3D
from vedo.utils import mag, precision
from brainrender.actor import Actor
[docs]
def ruler(
p1: npt.ArrayLike,
p2: npt.ArrayLike,
unit_scale: float = 1,
units: str | None = None,
s: float = 50,
) -> Actor:
"""
Create a ruler showing the distance between two points.
The ruler is composed of a line between the points and
a text indicating the distance.
Parameters
----------
p1
Coordinates of the first point.
p2
Coordinates of the second point.
unit_scale
Scale factor for the displayed units (e.g. 0.001 to show mm instead of µm).
units
Unit label string (e.g. ``"mm"``).
s
Text size. Default 50.
Returns
-------
Actor
A ruler actor showing the distance between the two points.
"""
logger.debug(f"Creating a ruler actor between {p1} and {p2}")
actors = []
# Make two line segments
midpoint = np.array([(x + y) / 2 for x, y in zip(p1, p2)])
gap1 = ((midpoint - p1) * 0.8) + p1
gap2 = ((midpoint - p2) * 0.8) + p2
actors.append(Line(p1, gap1, lw=200))
actors.append(Line(gap2, p2, lw=200))
# Add label
if units is None: # pragma: no cover
units = "" # pragma: no cover
dist = mag(p2 - p1) * unit_scale
label = precision(dist, 3) + " " + units
lbl = Text3D(label, pos=midpoint, s=s + 100, justify="center")
lbl.rotate_z(180, around=midpoint)
actors.append(lbl)
# Add spheres add end
actors.append(Sphere(p1, r=s, c=[0.3, 0.3, 0.3]))
actors.append(Sphere(p2, r=s, c=[0.3, 0.3, 0.3]))
act = Actor(merge(*actors), name="Ruler", br_class="Ruler")
act.c((0.3, 0.3, 0.3)).alpha(1).lw(2)
return act
def ruler_from_surface(
p1: npt.ArrayLike,
root: Actor,
unit_scale: float = 1,
axis: int = 1,
units: str | None = None,
s: float = 50,
) -> Actor:
"""
Create a ruler between a point and the brain's surface.
Parameters
----------
p1
Coordinates of the point.
root
Actor with the brain's root mesh.
unit_scale
Scale factor for the displayed units (e.g. 0.001 to show mm instead of µm).
axis
Index of the axis along which the distance is computed. Default 1.
units
Unit label string (e.g. ``"mm"``).
s
Text size. Default 50.
Returns
-------
Actor
A ruler actor showing the distance from the point to the brain surface.
"""
logger.debug(f"Creating a ruler actor between {p1} and brain surface")
# Get point on brain surface
p2 = p1.copy()
p2[axis] = 0 # zero the chosen coordinate
pts = root.mesh.intersect_with_line(p1, p2)
surface_point = pts[0]
return ruler(p1, surface_point, unit_scale=unit_scale, units=units, s=s)