Skip to main content

A library for working with hierarchical coordinate systems and transformations

Project description

Coordinatus

Simple coordinate transformations with hierarchical frames

Ever needed to convert coordinates between different spaces? Coordinatus makes it easy to work with nested coordinate systems—like transforming from a character's local space to world space, or from one object to another.

Note: Currently supports 2D Cartesian coordinates. Support for 3D, polar, and spherical coordinate systems is planned.

Why Coordinatus?

  • Intuitive API: Work with Points and Vectors that transform correctly (vectors ignore translation!)
  • Hierarchical Frames: Build parent-child relationships just like scene graphs in game engines
  • Clean transformations: Simple functions for translation, rotation, and scaling
  • Type-safe: Points and Vectors are distinct types with correct transformation behavior

Installation with uv

Modern python package manager uv is recommended for managing dependencies, but pip can also be used (simply replace uv add with pip install in example below).

uv add coordinatus

Installing the Development Version

To install the latest development version from the develop branch:

Using uv:

uv add git+https://github.com/ManuGira/Coordinatus.git@develop

Optional: Visualization Support

For plotting and visualization features (used in examples):

Using uv:

uv add coordinatus[plotting]

This installs matplotlib for the coordinatus.visualization module.

Quick Start

from coordinatus import Frame, Point, create_frame
import numpy as np

# Create a world frame
world = Frame()

# Create a car frame, positioned at (100, 50) in the world
car = create_frame(parent=world, tx=100, ty=50, angle_rad=np.pi/4)

# Create a wheel frame, offset (10, 0) from the car
wheel = create_frame(parent=car, tx=10, ty=0)

# A point at the wheel's center
point_in_wheel = Point(x=0, y=0, frame=wheel)

# Convert to world coordinates
point_in_world = point_in_wheel.to_absolute()
print(f"Wheel center in world: ({point_in_world.x}, {point_in_world.y})")

# Convert between any two frames
point_in_car = point_in_wheel.relative_to(car)
print(f"Wheel center in car frame: ({point_in_car.x}, {point_in_car.y})")

Core Concepts

Frames

A Frame represents a coordinate system with its own position, rotation, and scale. Frames can be nested to create hierarchies.

Points vs Vectors

  • Points represent positions and are affected by translation
  • Vectors represent directions/offsets and ignore translation
from coordinatus import Point, Vector, Frame, create_frame

frame = create_frame(parent=None, tx=10, ty=5)

# Point gets translated
point = Point(x=0, y=0, frame=frame)
absolute = point.to_absolute()  # (10, 5)

# Vector does NOT get translated
vector = Vector(x=1, y=0, frame=frame)
absolute_vec = vector.to_absolute()  # (1, 0) - only rotation/scale applied

Coordinate Conversion

Convert between any two frames in your hierarchy:

# Convert from frame_a to frame_b
point_in_a = Point(np.array([5, 3]), frame=frame_a)
point_in_b = point_in_a.relative_to(frame_b)

# Or get absolute (world) coordinates
point_in_world = point_in_a.to_absolute()

The Relativity of Coordinates

A fundamental concept in coordinate transformations is that the same geometry looks different depending on your point of view. The same F-shaped object can appear rotated, scaled, or sheared simply by changing which reference frame you're observing from.

Consider these three views of the same scene with an F-shaped object and two coordinate frames:

View from Frame 1

Frame1 View

The F shape appears undistorted in its canonical form because it was defined using Frame 1 coordinates. From this perspective, Frame 1's axes are the standard orthogonal x and y axes at the origin. Frame 2 (green) appears in a different position and orientation relative to Frame 1.

View from Absolute Space

Absolute View

In absolute (world) space, we see how the F shape actually looks in reality. Frame 1 (blue) is sheared and the F inherits this shearing. Frame 2 (green) is rotated and scaled. This reveals the true geometric relationships between all elements.

View from Frame 2

Frame2 View

From Frame 2's perspective, Frame 2 is now at the origin with standard axes. The same F shape appears with a completely different orientation and distortion, even though the geometry itself hasn't changed—only our reference frame has.

Key insight: Coordinates are not absolute—they depend on the observer. The F shape's numerical coordinates change in each view, but the shape's position in physical space remains constant. This is the essence of relative coordinate systems.

API Overview

Creating Frames

from coordinatus import Frame, create_frame
import numpy as np

# Manually with a transform matrix
frame = Frame(transform=my_matrix, parent=parent_frame)

# Or use the convenient factory
frame = create_frame(
    parent=parent_frame,
    tx=10, ty=5,           # Translation
    angle_rad=np.pi/4,     # Rotation
    sx=2, sy=2             # Scale
)

Transformation Utilities

from coordinatus.transforms import translate2D, rotate2D, scale2D, trs2D

# Individual transformations (2D)
t = translate2D(tx=10, ty=5)
r = rotate2D(angle_rad=np.pi/2)
s = scale2D(sx=2, sy=3)

# Combined TRS (Translation-Rotation-Scale)
transform = trs2D(tx=10, ty=5, angle_rad=np.pi/4, sx=2, sy=2)

Visualization (Optional)

from coordinatus.visualization import draw_frame_axes, draw_points
import matplotlib.pyplot as plt

# Create figure
fig, ax = plt.subplots()

# Draw frames and points
draw_frame_axes(ax, frame1, color='blue', label='Frame1')
draw_frame_axes(ax, frame2, color='green', label='Frame2')
draw_points(ax, [point1, point2], color='red')

plt.show()

Note: Requires uv add coordinatus[plotting]

Examples

Check out the examples/ folder for complete, runnable examples:

Testing

uv run pytest tests

License

MIT

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

coordinatus-0.3.0.tar.gz (12.3 kB view details)

Uploaded Source

Built Distribution

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

coordinatus-0.3.0-py3-none-any.whl (16.4 kB view details)

Uploaded Python 3

File details

Details for the file coordinatus-0.3.0.tar.gz.

File metadata

  • Download URL: coordinatus-0.3.0.tar.gz
  • Upload date:
  • Size: 12.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for coordinatus-0.3.0.tar.gz
Algorithm Hash digest
SHA256 e5f1e42c9c2750bdaaecd574ce9f3def856aa6586d383e92fd8ec454fd21d78a
MD5 a033e31ebb373b876d311d21edd5bec0
BLAKE2b-256 652433b388a1a1e54edc8f54eeb46e0239600e25669b2c1f7ee710f78f4cc0ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for coordinatus-0.3.0.tar.gz:

Publisher: publish.yml on ManuGira/Coordinatus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file coordinatus-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: coordinatus-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 16.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for coordinatus-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6033f79d8d2bff49961e2e65f5b45fe9b70e2989bc7a4d41024a884fd849a34e
MD5 cec0cb3c1279e7bd01512ae86443dc7a
BLAKE2b-256 3f3f908aaeff8d78af438775f92d140ae6ea64d3810e998a6ad5d2b5edf88e82

See more details on using hashes here.

Provenance

The following attestation bundles were made for coordinatus-0.3.0-py3-none-any.whl:

Publisher: publish.yml on ManuGira/Coordinatus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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