transform module#

Coordinate system transforms#

This module provides 2D transforms used in the JITX system to position objects within the design tree.

class Transform(translate, rotate=0, scale=(1, 1))[source]#

Transform represents a translate * rotate * scale (TRS) transform in that order, so scale is applied first, then rotate, and finally translate. Note that non-unit scale will typically not carry over into component and circuit placement, and while it can be used to compute a placement before it’s applied, the results may be unexpected, and should be avoided. Also note that because the transforms are internally stored as decomposed values, a non-uniform scale cannot be applied to another transform, as this would result in a shear.

Constructing a transform directly is typically only needed in niche cases, and more often than not it is better to use member methods of various objects (in JITX typically called at()) to transform the object.

Parameters:
  • translate (TypeAliasType) – Translation as (x, y).

  • rotate (float) – Optional rotation angle in degrees.

  • scale (float | tuple[float, float]) – Optional scale factors as (x, y). If a single value is provided, then the same value is used for both x and y.

>>> # Place a component at (10, 20) with 90° rotation
>>> xform = Transform((10, 20), rotate=90)
>>> # Use helper methods instead
>>> xform = Transform.translate(10, 20) * Transform.rotate(90)
>>> # Apply transform to a point
>>> point = (5, 0)
>>> new_point = xform * point
>>> print(new_point)
(10, 25)
clone()[source]#

Create a copy of this transform.

Returns:

New Transform with identical translation, rotation, and scale.

property trs#

Get the transform components as a tuple (translation, rotation, scale).

property translation: Point#

The transform’s translation as (x, y).

property rotation: float#

The transform’s rotation angle in degrees.

inverse()[source]#

Compute the inverse transform.

The inverse transform undoes the effect of this transform. Applying a transform followed by its inverse returns the original value.

Returns:

New Transform that is the inverse of this transform.

>>> t = Transform.translate(10, 20) * Transform.rotate(45)
>>> t_inv = t.inverse()
>>> point = (5, 5)
>>> # Applying transform then inverse returns original
>>> result = t_inv * (t * point)
>>> # result ≈ (5, 5)
matrix2x3(*, row_major=False, flat=False)[source]#

Convert transform to a 2x3 affine transformation matrix.

Returns the matrix representation of this transform, which can be used with graphics libraries or other systems that expect matrix form.

Parameters:
  • row_major – If True, return in row-major order; otherwise column-major (default).

  • flat – If True, return as flat tuple; otherwise as nested tuples (default).

Returns:

Matrix in the requested format (nested tuples or flat tuple).

>>> t = Transform.translate(10, 5) * Transform.rotate(90)
>>> # Get column-major nested format (default)
>>> m = t.matrix2x3()
>>> # m = ((0, 1), (-1, 0), (10, 5))
>>> # Get row-major flat format
>>> m = t.matrix2x3(row_major=True, flat=True)
>>> # m = (0, -1, 10, 1, 0, 5)
matrix3x3(*, row_major=False, flat=False)[source]#

Convert transform to a 3x3 homogeneous transformation matrix.

Returns the matrix representation as a 3x3 homogeneous matrix with the bottom row as [0, 0, 1], suitable for use with homogeneous coordinates.

Parameters:
  • row_major – If True, return in row-major order; otherwise column-major (default).

  • flat – If True, return as flat tuple; otherwise as nested tuples (default).

Returns:

3x3 matrix in the requested format (nested tuples or flat tuple).

>>> t = Transform.translate(10, 5)
>>> m = t.matrix3x3()
>>> # Column-major: ((1, 0, 0), (0, 1, 0), (10, 5, 1))
classmethod translate(x, y=None, /)[source]#

Create a translation-only transform.

Parameters:
  • x (float | TypeAliasType) – X translation or a (x, y) point.

  • y (float | None) – Y translation (not used if x is a point).

Returns:

New Transform with only translation (no rotation or scaling).

>>> # Translate by (10, 20)
>>> t = Transform.translate(10, 20)
>>> # Alternative using tuple
>>> t = Transform.translate((10, 20))
>>> # Use in component placement
>>> component.at(Transform.translate(5, 10))
classmethod rotate(angle)[source]#

Create a rotation-only transform.

Parameters:

angle (float) – Rotation angle in degrees (counter-clockwise).

Returns:

New Transform with only rotation (no translation or scaling).

>>> # Rotate 90 degrees counter-clockwise
>>> t = Transform.rotate(90)
>>> # Combine with translation
>>> t = Transform.translate(10, 0) * Transform.rotate(45)
classmethod scale(x, y=None, /)[source]#

Create a scale-only transform.

Parameters:
  • x (float) – X scale factor, or uniform scale if y is not provided.

  • y (float | None) – Y scale factor (optional, defaults to x for uniform scaling).

Returns:

New Transform with only scaling (no translation or rotation).

Note

Non-uniform scaling should be used with caution as it may not carry over properly to component placement.

>>> # Uniform scale by 2x
>>> t = Transform.scale(2)
>>> # Non-uniform scale
>>> t = Transform.scale(2, 1.5)  # 2x in X, 1.5x in Y
classmethod identity()[source]#

Create an identity transform (no transformation).

Returns:

New Transform that applies no transformation.

>>> t = Transform.identity()
>>> point = (5, 10)
>>> result = t * point
>>> # result == (5, 10)
class ImmutableTransform(translate, rotate=0, scale=(1, 1))[source]#

Bases: Transform

Parameters:
IDENTITY = Transform((0, 0), 0, (1, 1))#

Immutable identity transform constant.

class Vec2D(x, y)[source]#

A basic 2D vector class. Used internally for some calculations, not typically used in public APIs.

Parameters:
property x: float#
property y#
property xy: tuple[float, float]#
property length: float#
normalized()[source]#
Return type:

Vec2D

dot(other)[source]#
Return type:

float

Parameters:

other (Vec2D)

cross(other)[source]#

Compute the magnitude of the cross product.

Return type:

float

Parameters:

other (Vec2D)

angle()[source]#

Compute the angle in radians counter-clockwise from the +X axis of this vector

Return type:

float

transform_grid_point(xform, pt)[source]#

Transform a grid point by a transform.

Grid points are integer coordinates used in schematic symbol positioning. This function ensures the result remains on the integer grid.

Parameters:
  • xform (Transform) – Transform to apply.

  • pt (TypeAliasType) – Grid point as (x, y) integer tuple.

Return type:

TypeAliasType

Returns:

Transformed grid point.

Raises:

ValueError – If the transformation results in non-integer coordinates.

Examples

>>> t = Transform.translate(10, 5)
>>> grid_pt = (3, 4)
>>> new_pt = transform_grid_point(t, grid_pt)
>>> # new_pt = (13, 9)