Skip to main content

Hierarchical coordinate frames - crystal clear transforms

Project description

hazy-frames

Python Version License: MIT Code style: ruff Coverage Tests

Hierarchical coordinate frames - crystal clear transforms

A Python library for managing hierarchical reference frames and frame-aware geometric primitives with efficient transformation caching, inspired by optiland.

Features

  • Hierarchical Frame System: Build complex frame hierarchies with parent-child relationships
  • Frame-Aware Primitives: Point and Vector classes that carry frame information
  • Automatic Transformations: Transform primitives between any frames in the hierarchy
  • Efficient Caching: Transformation matrices are cached for performance
  • Proper Geometric Semantics: Type-safe arithmetic operations (e.g., Point - Point = Vector)
  • Flexible Transformations: Support for rotation (Euler angles, matrices), translation, and scaling
  • Global Reference Frame: Singleton global frame for world coordinates

Installation

Install directly from GitHub:

pip install git+https://github.com/Littie28/hazy-frames.git

Or download the wheel from releases:

pip install hazy_frames-0.1.0-py3-none-any.whl

For development:

# Clone the repository
git clone https://github.com/Littie28/hazy-frames.git
cd hazy-frames

# Install with development dependencies
uv sync --group dev

Quick Start

from hazy import Frame, Point, Vector

# Create a frame hierarchy
world = Frame.get_global()
robot = Frame(parent=world, name="robot")
robot.translate(x=5, y=0, z=0).rotate_euler(z=90, degrees=True)

camera = robot.make_child(name="camera")  # different initialization methods
camera.translate(x=0, y=0, z=1)

# Create frame-aware primitives
point_in_camera = Point(1, 0, 0, frame=camera)

# Transform between frames
point_in_world = point_in_camera.to_frame(world)
point_in_robot = point_in_camera.to_frame(robot)

print(f"Camera: {point_in_camera}")
print(f"World: {point_in_world}")
print(f"Robot: {point_in_robot}")

Core Concepts

Frames

Frames represent coordinate systems and can be organized hierarchically:

# Create frames
root = Frame.make_root(name="root")
parent = root.make_child("parent")
child = Frame(parent=parent, name="child")

# Apply transformations (chainable)
child.translate(x=10, y=5, z=0)
child.rotate_euler(x=45, y=0, z=90, degrees=True)
child.scale(2.0)  # uniform scaling
child.scale((1.0, 2.0, 1.5))  # non-uniform scaling

# Freeze frames to prevent modifications
child.freeze()

Transformations are applied in S->R->T order (Scale, Rotation, Translation) when converting from local to parent coordinates.

Points and Vectors

Points represent positions, vectors represent directions/displacements:

# Create primitives
origin = Point(0, 0, 0, frame=child)
direction = Vector(1, 0, 0, frame=child)

# Proper geometric arithmetic
point_a = Point(1, 2, 3, frame=child)
point_b = Point(4, 5, 6, frame=child)

displacement = point_b - point_a  # Returns Vector
new_point = point_a + displacement  # Returns Point

# Vectors support additional operations
vec = Vector(1, 0, 0, frame=child)
vec.normalize()  # Normalize in-place
magnitude = vec.magnitude

# Cross product
vec1 = Vector(1, 0, 0, frame=child)
vec2 = Vector(0, 1, 0, frame=child)
perpendicular = vec1.cross(vec2)  # Vector(0, 0, 1)

Frame Transformations

# Get transformation matrices
T_to_parent = frame.transform_to_parent  # 4x4 matrix
T_from_parent = frame.transform_from_parent  # Inverse
T_to_global = frame.transform_to_global  # To world frame
T_to_target = frame.transform_to(target_frame)  # To any frame

# Transform primitives
point_global = point_local.to_global()
point_target = point_local.to_frame(target_frame)

# Batch transformations for efficiency
points_array = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
transformed = frame.batch_transform_points_global(points_array)

Unit Vectors and Origin

Frames provide convenient accessors for unit vectors and origin:

# Unit vectors in frame's local coordinates
x_axis = frame.x_axis 
y_axis = frame.y_axis
z_axis = frame.z_axis

# Unit vectors in global coordinates
x_global = frame.x_axis_global
y_global = frame.y_axis_global
z_global = frame.z_axis_global

# Frame origin
origin_local = frame.origin  # Point(0, 0, 0) in frame
origin_global = frame.origin_global  # Origin in global coords

API Overview

Frame Class

Method/Property Description
translate(x, y, z) Add translation to frame
rotate_euler(x, y, z, seq, degrees) Add Euler angle rotation
rotate(matrix) Add rotation from 3x3 matrix
scale(factor) Add scaling (uniform or non-uniform)
freeze()/unfreeze() Prevent/allow modifications
transform_to_parent 4x4 transformation matrix to parent
transform_to_global 4x4 transformation matrix to global
transform_to(target) 4x4 transformation matrix to target frame
point(x, y, z) Create Point in this frame
vector(x, y, z) Create Vector in this frame

Point Class

Method/Property Description
to_frame(target) Transform to target frame
to_global() Transform to global frame
x, y, z Coordinate components
Point + Vector Returns Point (displacement)
Point - Point Returns Vector (difference)
Point - Vector Returns Point (reverse displacement)

Vector Class

Method/Property Description
to_frame(target) Transform to target frame
to_global() Transform to global frame
x, y, z Vector components
magnitude Vector length
normalize() Normalize to unit length (in-place)
cross(other) Cross product with another vector
Vector + Vector Returns Vector (sum)
Vector - Vector Returns Vector (difference)
Vector + Point Returns Point (displacement)

Development

Running Tests

# Run all tests
pytest

# Run with coverage
pytest --cov=src/hazy --cov-report=html

# Run specific test markers
pytest -m unit
pytest -m integration

# Watch mode for development
pytest-watcher

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hazy_frames-0.1.0.tar.gz (131.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hazy_frames-0.1.0-py3-none-any.whl (15.8 kB view details)

Uploaded Python 3

File details

Details for the file hazy_frames-0.1.0.tar.gz.

File metadata

  • Download URL: hazy_frames-0.1.0.tar.gz
  • Upload date:
  • Size: 131.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"26.05","id":"yarara","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for hazy_frames-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3f90386365677706feb69b08048a60435b79f0fea8410911e2a6c4298652bd13
MD5 f3461eab57c13f5edef62b648ed8f92d
BLAKE2b-256 1151a8d8fa9c671e976b91657d11c47d533e9086bcda317a2b2d7216722d6fba

See more details on using hashes here.

File details

Details for the file hazy_frames-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: hazy_frames-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"26.05","id":"yarara","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for hazy_frames-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f947502a31ae9d57c9669eeef82eb7b7fce235aab5881898f1ce312337f6636d
MD5 7ed44da574a1c9b357d1d982bbc408c5
BLAKE2b-256 9089d8aac90941c32de9a97821db9920f6d72d0009ad0bfc793034c3596952cc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page