Geometry
Module: terminaltexteffects.utils.geometry
Balanced Grids
New in 0.16.0
find_balanced_grid() and GridLayout are available on development main and are not in the published
0.15.0 package.
find_balanced_grid(left, bottom, right, top) returns a GridLayout covering inclusive bounds. It accounts for
terminal character height when choosing row and column counts, then divides each axis so cell sizes differ by
at most one position. target_cells, min_cell_width, and min_cell_height control the preferred size.
The layout's column_boundaries and row_boundaries include an exclusive final boundary, one beyond the
canvas edge. Each cell includes its lower boundaries and excludes its upper boundaries. For example,
an 80-column by 24-row canvas produces five columns of cells and three rows, with cells measuring 16 by 8.
Utility functions for geometric calculations and operations.
The purpose of these functions is to find terminal coordinates that fall within certain regions or along certain paths. These functions are used by effects to enable more complex animations and movement paths.
Functions:
| Name | Description |
|---|---|
find_balanced_grid |
Divides inclusive bounds into nearly square cells of balanced size. |
find_coords_on_circle |
Finds points on a circle given the origin, radius, and number of points. |
find_coords_in_circle |
Finds coordinates within a terminal-adjusted circle given its center and radius. |
find_coords_in_rect |
Finds coordinates within a rectangle given the origin and distance. |
rasterize_line |
Rasterizes a thin line between two terminal coordinates. |
rasterize_supercover_line |
Rasterizes every terminal cell touched by a line. |
extrapolate_along_ray |
Finds the coordinate past a target along the ray from an origin. |
find_coord_on_bezier_curve |
Evaluates a Bézier curve at a parameter value. |
interpolate_coord |
Linearly interpolates or extrapolates between two coordinates. |
find_coord_on_line |
Compatibility alias for |
find_length_of_bezier_curve |
Approximates the length of a Bézier curve of any degree. |
find_length_of_line |
Finds the length of a line intersecting two coordinates. |
find_normalized_distance_from_center |
Returns the normalized distance from the center of the Canvas. |
Constants
TERMINAL_ROW_SCALE: Approximate terminal-cell height relative to its width.
TERMINAL_ROW_SCALE = 2
module-attribute
Approximate terminal-cell height relative to its width.
extrapolate_along_ray = functools.wraps(extrapolate_along_ray)(functools.lru_cache(maxsize=8192)(extrapolate_along_ray))
module-attribute
Return the point offset_from_target units past target along the origin -> target ray.
A positive offset continues past target away from origin, while a negative offset
moves back toward and potentially past origin. If origin and target coincide,
the direction is undefined and target is returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
origin
|
Coord
|
origin coordinate (a) |
required |
target
|
Coord
|
target coordinate (b) |
required |
offset_from_target
|
float
|
Signed distance from the target coordinate (b). |
required |
terminal_adjusted
|
bool
|
Whether distance accounts for terminal cell height. Defaults to True. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
Coord |
Coord
|
Coordinate at the given distance (c). |
find_coord_on_bezier_curve = functools.wraps(find_coord_on_bezier_curve)(functools.lru_cache(maxsize=16384)(find_coord_on_bezier_curve))
module-attribute
Evaluate a Bézier curve of any degree at parameter t.
Values of t between 0 and 1 evaluate the curve from start to end.
Values outside that interval intentionally extrapolate beyond the curve endpoints.
An empty control-point tuple describes a linear Bézier curve.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
Coord
|
The starting coordinate of the curve. |
required |
control
|
tuple[Coord, ...] | Coord
|
A single control point or tuple of control points. |
required |
end
|
Coord
|
The ending coordinate of the curve. |
required |
t
|
float
|
The unrestricted Bézier parameter. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
Coord |
Coord
|
The rounded coordinate at |
find_coord_on_line = interpolate_coord
module-attribute
Compatibility alias for interpolate_coord.
find_coords_in_circle = _cache_coordinate_list(_CIRCLE_AREA_CACHE_SIZE)(find_coords_in_circle)
module-attribute
Find coordinates within a terminal-adjusted circle.
The generated coordinate-space ellipse has a horizontal radius of radius columns and a
vertical radius of radius / TERMINAL_ROW_SCALE rows. With terminal cells approximately
TERMINAL_ROW_SCALE times as tall as they are wide, this ellipse appears circular. A radius
of 0 returns only center.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
center
|
Coord
|
The center coordinate of the circle. |
required |
radius
|
int
|
The terminal-adjusted circle radius, measured in column-distance units. |
required |
Returns:
| Type | Description |
|---|---|
list[Coord]
|
list[Coord]: A list of coordinates within the circle. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
find_coords_in_rect = _cache_coordinate_list(_COORDINATE_LIST_CACHE_SIZE)(find_coords_in_rect)
module-attribute
Find coords that fall within a rectangle.
Distance specifies the number of units in each direction from the origin.
The resulting rectangle has width and height 2 * distance + 1, so a distance
of 0 returns only origin.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
origin
|
Coord
|
center of the rectangle |
required |
distance
|
int
|
distance from the origin |
required |
Returns:
| Type | Description |
|---|---|
list[Coord]
|
list[Coord]: list of Coord points in the rectangle |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
find_coords_on_circle = _cache_coordinate_list(_COORDINATE_LIST_CACHE_SIZE)(find_coords_on_circle)
module-attribute
Find points on a terminal-adjusted circle.
The generated coordinate-space ellipse has a horizontal radius of radius columns and a
vertical radius of radius // TERMINAL_ROW_SCALE rows. With terminal cells approximately
TERMINAL_ROW_SCALE times as tall as they are wide, this ellipse appears circular. A radius
of 0 returns only origin.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
origin
|
Coord
|
origin of the circle |
required |
radius
|
int
|
terminal-adjusted circle radius, measured in column-distance units |
required |
coords_limit
|
int
|
limit the number of coords returned, if 0, the number of points is calculated based on the circumference of the circle |
required |
unique
|
bool
|
whether to remove duplicate points. Defaults to True. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
list |
Coord
|
list of Coord points on the circle |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
find_coords_on_rect = _cache_coordinate_list(_COORDINATE_LIST_CACHE_SIZE)(find_coords_on_rect)
module-attribute
Find coords on the perimeter of a rectangle.
Half width and half height specify the distance in each direction from the origin.
Returns coordinates that fall on the perimeter (edges) of the rectangle only.
If one half-dimension is 0, the rectangle collapses to a vertical or horizontal
line. If both are 0, only origin is returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
origin
|
Coord
|
center of the rectangle |
required |
half_width
|
int
|
half the width of the rectangle |
required |
half_height
|
int
|
half the height of the rectangle |
required |
Returns:
| Type | Description |
|---|---|
list[Coord]
|
list[Coord]: list of Coord points in the rectangle |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
find_length_of_bezier_curve = functools.wraps(find_length_of_bezier_curve)(functools.lru_cache(maxsize=4096)(find_length_of_bezier_curve))
module-attribute
Approximate the length of a Bézier curve of any degree.
The curve length is calculated from unrounded floating-point points using adaptive
subdivision. A single Coord or a tuple of control points is accepted, matching
find_coord_on_bezier_curve; an empty tuple describes a linear Bézier curve. By
default, row distances are scaled according to the terminal character aspect ratio.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
Coord
|
The starting coordinate of the curve. |
required |
control
|
tuple[Coord, ...] | Coord
|
A single control point or tuple of control points. |
required |
end
|
Coord
|
The ending coordinate of the curve. |
required |
terminal_adjusted
|
bool
|
Whether distance accounts for terminal cell height. Defaults to True. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
float |
float
|
The approximate length of the Bézier curve. |
find_length_of_line = functools.wraps(find_length_of_line)(functools.lru_cache(maxsize=8192)(find_length_of_line))
module-attribute
Return the distance between two coordinates.
By default, row distances are scaled according to the terminal character aspect ratio.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
coord1
|
Coord
|
first coordinate. |
required |
coord2
|
Coord
|
second coordinate. |
required |
terminal_adjusted
|
bool
|
Whether distance accounts for terminal cell height. Defaults to True. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
float |
float
|
length of the line |
find_normalized_distance_from_center = functools.wraps(find_normalized_distance_from_center)(functools.lru_cache(maxsize=8192)(find_normalized_distance_from_center))
module-attribute
Return the normalized distance from the center of a rectangle on the Canvas as a float between 0 and 1.
The distance is calculated using the Pythagorean theorem and accounts for the aspect ratio of the terminal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bottom
|
int
|
Bottom row of the rectangle on the Canvas. |
required |
top
|
int
|
Top row of the rectangle on the Canvas. |
required |
left
|
int
|
Left column of the rectangle on the Canvas. |
required |
right
|
int
|
Right column of the rectangle on the Canvas. |
required |
other_coord
|
Coord
|
Other coordinate from which to calculate the distance to the center of the rectangle. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
float |
float
|
Normalized distance from the center of the rectangle on the Canvas, float between 0 and 1. |
interpolate_coord = functools.wraps(interpolate_coord)(functools.lru_cache(maxsize=16384)(interpolate_coord))
module-attribute
Linearly interpolate or extrapolate between two coordinates.
A value of 0 returns start, 1 returns end, and values outside the
inclusive interval [0, 1] intentionally extrapolate beyond the endpoints.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
Coord
|
The starting coordinate of the line. |
required |
end
|
Coord
|
The ending coordinate of the line. |
required |
t
|
float
|
The unrestricted linear interpolation parameter. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
Coord |
Coord
|
The rounded coordinate at |
rasterize_line = _cache_coordinate_list(_COORDINATE_LIST_CACHE_SIZE)(rasterize_line)
module-attribute
Return a thin, one-cell-wide rasterization from start to end.
Bresenham's line algorithm selects one terminal-grid coordinate at each step along
the dominant axis. Both endpoints are included, coordinates are unique and ordered
from start to end, and reversing the endpoints reverses the result. Coincident
endpoints return a one-coordinate list. Terminal aspect-ratio scaling is not applied.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
Coord
|
The first endpoint. |
required |
end
|
Coord
|
The second endpoint. |
required |
Returns:
| Type | Description |
|---|---|
list[Coord]
|
list[Coord]: Ordered coordinates forming the rasterized line. |
rasterize_supercover_line = _cache_coordinate_list(_COORDINATE_LIST_CACHE_SIZE)(rasterize_supercover_line)
module-attribute
Return every terminal-grid cell touched by the line from start to end.
Both endpoints are included, coordinates are unique and ordered from start to
end, and reversing the endpoints reverses the result. When the line passes exactly
through a grid corner, both adjacent cells are included to preserve complete coverage.
Coincident endpoints return a one-coordinate list. Terminal aspect-ratio scaling is
not applied.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
Coord
|
The first endpoint. |
required |
end
|
Coord
|
The second endpoint. |
required |
Returns:
| Type | Description |
|---|---|
list[Coord]
|
list[Coord]: Ordered coordinates forming the supercover line. |
Coord
dataclass
A coordinate with row and column values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
column
|
int
|
column value |
required |
row
|
int
|
row value |
required |
Source code in terminaltexteffects/utils/geometry.py
__iter__()
Allow tuple unpacking by yielding the column and row.
Yields:
| Type | Description |
|---|---|
int
|
column, row: yield the column, followed by the row |
GridLayout
dataclass
Describe rectangular cells using increasing column and row boundaries.
Each cell includes its lower boundaries and excludes its upper boundaries. The last boundary is therefore one beyond the inclusive canvas edge.
Attributes:
| Name | Type | Description |
|---|---|---|
column_boundaries |
tuple[int, ...]
|
Left-to-right column boundaries. |
row_boundaries |
tuple[int, ...]
|
Bottom-to-top row boundaries. |
Source code in terminaltexteffects/utils/geometry.py
__post_init__()
Reject boundaries that would produce empty or overlapping cells.
Source code in terminaltexteffects/utils/geometry.py
find_balanced_grid(left, bottom, right, top, *, target_cells=5, min_cell_width=4, min_cell_height=2)
Divide inclusive bounds into balanced, approximately square terminal cells.
Aim for target_cells along the longer visual axis, reducing the target
cell size for narrow canvases. Compare nearby row and column counts for
squareness and proximity to that size, using TERMINAL_ROW_SCALE.
Cell widths and heights each differ by at most one position. Minimum sizes
limit subdivision; a smaller canvas retains one cell along that axis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
left
|
int
|
Inclusive left column. |
required |
bottom
|
int
|
Inclusive bottom row. |
required |
right
|
int
|
Inclusive right column. |
required |
top
|
int
|
Inclusive top row. |
required |
target_cells
|
int
|
Preferred cell count along the longer visual axis. |
5
|
min_cell_width
|
int
|
Minimum columns per cell when space permits. |
4
|
min_cell_height
|
int
|
Minimum rows per cell when space permits. |
2
|
Returns:
| Name | Type | Description |
|---|---|---|
GridLayout |
GridLayout
|
Boundaries covering the complete rectangle. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If bounds are not ordered integers or sizing options are not positive integers. |
Source code in terminaltexteffects/utils/geometry.py
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | |