alignment#

Geometric alignment utilities for diagram layouts.

This module provides helpers to: - Rotate a set of circles to a canonical orientation using PCA on their centers. - Place multiple (layout, circles) pairs side by side with a consistent gap.

Heavy dependencies (e.g., scikit-learn) are imported locally inside the functions that need them, so importing knotpy.drawing remains fast.

Functions

align_layouts(layout_circles_pairs)

Place multiple layouts side-by-side with a uniform horizontal gap.

canonically_rotate_circles(circles[, degree])

Rotate a system of circles to a canonical orientation via PCA.

canonically_rotate_circles(circles, degree=0)#

Rotate a system of circles to a canonical orientation via PCA.

Given a mapping where values are Circle instances, compute the PCA of their centers (weighted by radius for the mass center), translate to the center of mass, align with the first principal component, optionally rotate by degree (degrees), and (if needed) flip so more mass lies to the right (positive real axis).

If degree = 0, the primary axis aligns horizontally (i.e., circles are visually “laid out” left–right).

Parameters:
  • circles (dict) – A dict whose values are Circle objects.

  • degree (int) – Additional rotation in degrees applied after PCA alignment.

Returns:

dict – A new dict with the same keys, where each value is a rotated Circle (centers transformed; radii preserved).

Raises:

ValueError – If any value in circles is not a Circle.

Return type:

dict

align_layouts(layout_circles_pairs)#

Place multiple layouts side-by-side with a uniform horizontal gap.

This function translates each subsequent layout (and its companion circles) so that their bounding boxes are laid out left-to-right with a fixed gap.

Parameters:

layout_circles_pairs (list[tuple[dict, dict]]) –

A list of pairs (layout, circles):
  • layout: dict mapping identifiers to complex points (positions).

  • circles: dict mapping identifiers to Circle objects.

Both dicts are modified in place.

Returns:

None. The input dictionaries are translated in place.

Return type:

None

Notes

  • The horizontal gap equals twice the mean radius across all provided circles (averaged per pair, then across pairs).