Skip to main content

A modern python library for 3D homogenous transforms and coordinate system utilities.

Project description

Polyframe

PyPI version
License

A fast, flexible, zero-cost Python library for 3D homogeneous transforms and arbitrary coordinate-system conventions.


🚀 Features

  • Arbitrary Cartesian frames
    Define any right- or left-handed (x,y,z) basis via a simple enum.
    Zero-cost: all “bring your own conventions” work happens at import time.

  • Flexible spherical conventions
    Compute azimuth/elevation, φ/θ or latitude/longitude with pluggable:

    • signed vs. unsigned angles
    • CW vs. CCW positive rotation
    • polar vs. elevation definitions
    • custom “up”/“forward”/“lateral” axes
  • Effortless re-framing
    Change the basis of a Transform in one call:

    from polyframe import FrameRegistry, Direction, Transform
    
    tr_world = Transform.from_values(translation=[1,2,3])
    cs_robot = FrameRegistry.from_directions(
        Direction.RIGHT, Direction.FORWARD, Direction.UP
    )
    tr_robot = tr_world.change_coordinate_system(cs_robot)
    
  • Quaternion & Euler support
    Apply quaternion or Euler rotations directly:

    tr = Transform()
    tr_q = tr.apply_quaternion([0,0,0,1])           # [x,y,z,w]
    tr_e = tr.apply_euler_rotation(roll, pitch, yaw)
    
  • Distance & direction utilities

    • distance_to(), vector_to(), direction_to()
  • Numba-accelerated core routines
    Under the hood, heavy linear-algebra paths (look_at, angle computations, quaternion ↔ matrix) are JIT-compiled for max throughput.

  • Memory-efficient
    Coordinate frames are static types; no per-instance overhead for storing conventions.


📦 Installation

pip install polyframe

🎬 Quickstart

from polyframe import FrameRegistry, Direction, Transform

# 1) identity at origin, facing +X
tr = Transform()

# 2) translate to (1,2,3)
tr = tr.apply_translation([1,2,3])

# 3) rotate via Euler angles
tr = tr.apply_euler_rotation(roll=0, pitch=45, yaw=90)

# 4) apply a quaternion
tr = tr.apply_quaternion([0,0,0,1])  # x,y,z,w

# 5) make it look at a point
tr = tr.look_at([4,5,6])

# 6) compute spherical angles
az, el, rng = tr.az_el_range_to([7,8,9])

# 7) compute φ/θ
phi, theta = tr.phi_theta_to([1,1,0])

# 8) distance/direction helpers
dist = tr.distance_to([2,2,2])
vec  = tr.vector_to([2,2,2])
dirn = tr.direction_to([2,2,2])

# 9) re-frame into a robot basis
robot_cs = FrameRegistry.from_directions(
    Direction.FORWARD, Direction.DOWN, Direction.LEFT
)
tr_robot = tr.change_coordinate_system(robot_cs)

🔍 Coordinate-System Conventions

Cartesian frames

Choose from any of 48 valid (x_dir,y_dir,z_dir) triples:

from polyframe import Direction, FrameRegistry

# World: X forward, Y left, Z up
world_cs = FrameRegistry.from_directions(
    Direction.FORWARD,
    Direction.LEFT,
    Direction.UP,
)

# Robot: X right, Y forward, Z down
robot_cs = FrameRegistry.from_directions(
    Direction.RIGHT,
    Direction.FORWARD,
    Direction.DOWN,
)

Each frame type exposes .forward / .backward / .left / .right / .up / .down unit vectors.

Spherical coordinates

  • Azimuth/Elevation (az_el_range_to)
  • Longitude/Latitude (lat_lon_to)
  • φ/θ (polar) (phi_theta_to)

All accept flags:

Flag Meaning
degrees degrees (default) or radians
signed_* signed (±180°/π) vs. unsigned (0…360°/2π)
counterclockwise_* CCW-positive vs. CW-positive
polar (φ/θ only) θ as polar (0…π) vs. elevation (±90°)
flip_* flip sign of elevation/latitude/θ

⚙️ API Highlights

from polyframe import Transform

# Construction
tr = Transform()                             # identity
tr2 = Transform.from_values(
    translation=[1,2,3],
    rotation=[[...]],    # 3×3
    scale=[2,2,2],
)

# Translation / Rotation / Scale
tr_t = tr.apply_translation([1,0,0])
tr_r = tr.apply_rotation(R)                  # 3×3
tr_q = tr.apply_quaternion(q)                # 4-vector [x,y,z,w]
tr_e = tr.apply_euler_rotation(roll,pitch,yaw)
tr_s = tr.apply_scale([2,3,4])

# Inverse / Combine
inv    = tr.inverse()
inv_ip = tr.inverse(inplace=True)
C      = tr @ tr2                            # compose

# Point / Vector
p2 = tr.transform_point([1,2,3])
v2 = tr.transform_vector([1,0,0])

# Re-frame
tr_new = tr.change_coordinate_system(other_frame)

# Look-at
tr_look = tr.look_at([x,y,z])

# Distance & Direction
d = tr.distance_to([x,y,z])
v = tr.vector_to([x,y,z])
dir = tr.direction_to([x,y,z])

# Angles
az, el, rng = tr.az_el_range_to([x,y,z])
phi, th     = tr.phi_theta_to([x,y,z])
lat, lon    = tr.lat_lon_to([x,y,z])

See the full docs.


🤝 Contributing

  1. Fork
  2. Add a branch
  3. Write tests under tests/
  4. PR — must pass CI (including Numba builds)

📄 License

Apache 2.0 — see LICENSE.

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

polyframe-0.1.5.tar.gz (30.1 kB view details)

Uploaded Source

Built Distribution

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

polyframe-0.1.5-py3-none-any.whl (21.4 kB view details)

Uploaded Python 3

File details

Details for the file polyframe-0.1.5.tar.gz.

File metadata

  • Download URL: polyframe-0.1.5.tar.gz
  • Upload date:
  • Size: 30.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for polyframe-0.1.5.tar.gz
Algorithm Hash digest
SHA256 ca4eb56a4d99d01d8296550d1103a7355b4f9be9a398f960ca9b828ac62eabe4
MD5 05fd1e980ee19d0ff9a2773b5c8bc7c2
BLAKE2b-256 8ffdf776758974da66af1c0b918dd9c3d2c8d470ab02bd3e67dc0af0093ea4ec

See more details on using hashes here.

File details

Details for the file polyframe-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: polyframe-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 21.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for polyframe-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 83b2228b998182443bae47097cedf8c960800ee16c983f615a0e3803b8c5e335
MD5 c7d0e989aca789606b5d9808282357d6
BLAKE2b-256 33e1ab33d70c86e96138f103abf8bf1cd0abc64d80f730aec049203638b4563b

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