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_basis_to(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_basis_to(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_basis_to(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.3.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.3-py3-none-any.whl (21.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: polyframe-0.1.3.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.3.tar.gz
Algorithm Hash digest
SHA256 e49ce5c89a863c8c05e88e070c97ede3774bb8526f72579634c6514f8f97e53f
MD5 6c051981b866d4ef42d9b5380ce20027
BLAKE2b-256 e1435b5e9414bb1592f4d951ed90cfc1732f4472589004ac672b2ed1f4072320

See more details on using hashes here.

File details

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

File metadata

  • Download URL: polyframe-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 21.1 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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 ef99810274098350b950fbec2c34f3b7dd62e520100dac99814d3950e9e77442
MD5 8e26b15c194a8f5cc29f426e85b97713
BLAKE2b-256 752d2d9991e657d3bb576fa66977e5424fee691903173c477eaa958c6264b565

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