Skip to content

Point2D

Represents a single 2D point.

Parameters

FieldTypeDescription
datanp.ndarray | list | tupleArray-like input, converted to a contiguous float32 array of shape (2,): [x, y].

Raises

ExceptionCondition
TypeErrordata can't be converted to a float32 array (e.g. ragged nested lists, non-numeric elements)
ValueErrorThe converted array isn't 1-D, its length isn't 2, or it contains a non-finite value (NaN/Inf)

Attributes

AttributeTypeDescription
datanp.ndarrayThe wrapped point, shape (2,). Reading it returns a copy, so mutating the result doesn't affect the Point2D; assigning a new value re-validates it the same way as construction.
shapetuple[int, ...]Always (2,).
ndimintAlways 1.
dtypenp.dtypeAlways float32.
sizeintAlways 2.
shape_specClassVar[tuple[int, ...]]Class-level shape contract, (2,), inherited from Vector2D. Same for every Point2D instance.

Methods

MethodDescription
to_numpy(copy=True)Returns the point as np.ndarray, shape (2,). Pass copy=False to get a reference to the internal array instead — faster, but mutating it mutates the Point2D too.
copy()Returns a new Point2D with an independent copy of the data.
Point2D.coerce(value)Returns value unchanged if it's already a Point2D; wraps a np.ndarray/list/tuple into one otherwise. Raises TypeError for anything else — including a plain Vector2D, since isinstance against Point2D doesn't match its own parent class.

Operators

OperationBehavior
point == otherTrue only if other is also exactly a Point2D (not a Vector2D or any other type, even with identical coordinates) with equal values (NaN counts as equal to NaN). False for anything else.
len(point)Always 2 — the length of axis 0 of the underlying (2,) array, not a "number of points" count.
np.asarray(point)Works directly — NumPy functions accept a Point2D in place of an np.ndarray. Always returns a copy; use to_numpy(copy=False) for a zero-copy view.
point + arr, point - arr, point * arr, point / arrNot implemented on Point2D itself (no __add__/__array_ufunc__). Verified empirically: with a NumPy array operand, NumPy coerces the Point2D via __array__ and performs plain elementwise arithmetic — the result is a plain np.ndarray, not a Point2D.
hash(point)Not supported — raises TypeError: unhashable type: 'Point2D'.

Visualization

datatypes.visualize(point, entity_path=..., label=...) logs the point as a single rerun 2D point (rr.Points2D(positions=point.data.reshape(1, 2))) — the same handler also backs Position2D. Pass label as a single str to additionally render a floating text label at the point's position.

Example

python
"""Demonstrates the Telekinesis Point2D datatype."""

import time

import numpy as np
from loguru import logger
import rerun as rr

from telekinesis import datatypes

def point2d_example():
    """Demonstrate creation, access, visualization, update, NumPy arithmetic, and serialization."""

    # ======================= Create ============================================
    point = [1.0, 2.0]
    point2d = datatypes.Point2D(point)

    logger.info(f"Original Point2D: {point2d}")

    # ======================= Inspect ===========================================
    data = point2d.data
    shape = point2d.shape
    size = point2d.size
    dtype = point2d.dtype
    ndim = point2d.ndim
    numpy_point2d = point2d.to_numpy()
    point2d_copy = point2d.copy()

    logger.info(f"shape={shape}, size={size}, ndim={ndim}, dtype={dtype}")
    logger.info(f"Underlying data: {data}")
    logger.info(f"NumPy array: {numpy_point2d}")
    logger.info(f"Copy: {point2d_copy}")

    # ======================= Visualize =========================================
    rr.init("point2d_example", spawn=True)
    datatypes.visualize(point2d, entity_path="/Point2D", label="My Point2D")

    # ======================= Update ============================================
    new_data = [3.0, 4.0]
    point2d.data = new_data
    logger.info(f"Updated Point2D: {point2d}")
    datatypes.visualize(point2d, entity_path="/Point2D/updated", label="Updated Point2D")

    # ======================= Arithmetic ========================================
    point_sum = point2d + np.array([1.0, 1.0])
    point_diff = point2d - np.array([1.0, 1.0])
    point_prod = point2d * np.array(2.0)
    point_quot = point2d / np.array(2.0)
    logger.info(f"Sum: {point_sum}, Difference: {point_diff}")
    logger.info(f"Product: {point_prod}, Quotient: {point_quot}")

    # ======================= Serialize / Deserialize ===========================
    start = time.perf_counter()
    serialized = datatypes.serialize(point2d)
    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 Point2D: {deserialized}")
    logger.info(f"Round-trip successful: {deserialized.data == new_data}")
    logger.info(f"Serialization time: {serialization_ms:.3f} ms")
    logger.info(f"Deserialization time: {deserialization_ms:.3f} ms")


if __name__ == "__main__":
    point2d_example()