Circle
Represents one circle: a center and a radius.
Parameters
| Field | Type | Description |
|---|---|---|
center | list[float] | np.ndarray | Circle center, converted to a contiguous float32 array of shape (2,): [x, y]. |
radius | float | Circle radius, must be >= 0. |
Raises
| Exception | Condition |
|---|---|
ValueError | center's shape (after conversion) isn't (2,), or radius < 0 |
Conversion of center to float32 (np.asarray(center, dtype=np.float32)) isn't wrapped in a try/except, so a value NumPy can't cast (e.g. a non-numeric string) raises whatever NumPy itself produces instead of a uniform Circle-specific error — empirically, Circle(center=["a", "b"], radius=1.0) raises ValueError: could not convert string to float: 'a', but other inputs could just as easily surface a TypeError.
Attributes
| Attribute | Type | Description |
|---|---|---|
center | np.ndarray | Defensive copy of the circle center, shape (2,), float32. |
radius | float | The circle radius. |
Methods
| Method | Description |
|---|---|
translate(offset) | Returns a new Circle with center shifted by offset (array-like [dx, dy]). radius unchanged. |
scale(factor) | Returns a new Circle with radius multiplied by factor. center unchanged. |
Circle.coerce(value) | Returns value unchanged if it's already a Circle; builds one from a dict with keys center and radius otherwise. Raises TypeError for anything else. |
Operators
| Operation | Behavior |
|---|---|
circle == other | True only if other is a Circle with an equal center (elementwise) and an equal radius. NotImplemented (so False) for any other type. |
hash(circle) | Not supported, despite being immutable after construction (__hash__ = None). |
repr(circle) | Circle(center=[50. 60.], radius=10.0) — verified empirically. |
Visualization
datatypes.visualize(circle, entity_path=..., label=...) logs the circle as a rerun ellipse with equal half-sizes on both axes (rr.Ellipses2D(centers=circle.center.reshape(1, 2), half_sizes=[[radius, radius]])), which renders as a true circle rather than a bounding box. Pass label as a single str to render a floating text label at the circle's center.
Example
"""Demonstrates the Telekinesis Circle datatype."""
import time
import numpy as np
from loguru import logger
import rerun as rr
from telekinesis import datatypes
def circle_example():
"""Demonstrate creation, access, translation and scaling of the immutable Circle, visualization, and serialization."""
# ======================= Create ============================================
circle = datatypes.Circle(center=[50.0, 60.0], radius=10.0)
logger.info(f"Original Circle: {circle}")
# ======================= Inspect ===========================================
logger.info(f"center={circle.center}, radius={circle.radius}")
# ======================= Translate / Scale =================================
translated = circle.translate([5.0, 5.0])
scaled = translated.scale(1.5)
logger.info(f"Translated Circle: {translated}")
logger.info(f"Scaled Circle: {scaled}")
# ======================= Visualize =========================================
rr.init("circle_example", spawn=True)
datatypes.visualize(circle, entity_path="/Circle", label="My Circle")
datatypes.visualize(scaled, entity_path="/Circle/updated", label="Updated Circle")
# ======================= Serialize / Deserialize ===========================
start = time.perf_counter()
serialized = datatypes.serialize(scaled)
serialization_ms = (time.perf_counter() - start) * 1000
start = time.perf_counter()
deserialized = datatypes.deserialize(serialized)["param_0"]
deserialization_ms = (time.perf_counter() - start) * 1000
logger.info(f"Deserialized Circle: {deserialized}")
logger.info(f"Round-trip successful: {scaled == deserialized}")
logger.info(f"Serialization time: {serialization_ms:.3f} ms")
logger.info(f"Deserialization time: {deserialization_ms:.3f} ms")
if __name__ == "__main__":
circle_example()
