gscrib.geometry
Utilities for path generation and transformations.
This module provides tools for working with geometric paths and coordinate transformations. It includes functionality for tracing paths and applying transformations to coordinate systems.”
- class gscrib.geometry.BoundManager
Bases:
objectBounds manager and validator.
- get_bounds(name)
Retrieve the bounds for a given property.
- Parameters:
name (str) – Parameter name
- Returns:
The min and max bounds
- Return type:
Tuple[Bound, Bound]
- set_bounds(name, min, max)
Set the bounds for a given property.
- Parameters:
name (str) – The property for which bounds are being set.
min (Bound) – The minimum value of the property.
max (Bound) – The maximum value of the property.
- Raises:
ValueError – If bounds are not valid or property is unknown.
TypeError – If the type of min/max is incorrect.
- Return type:
None
- validate(name, value)
Validate whether a given value is within bounds.
- Parameters:
- Raises:
ValueError – If bounds where defined for the property and the provided value is outside bounds.
- Return type:
None
- class gscrib.geometry.CoordinateTransformer
Bases:
objectCoordinate system transformations using 4x4 matrices.
This class provides methods for transforming the coordinate system through operations such as translation, rotation, scaling, and reflection. It maintains a transformation stack for nested transformations.
Transformations are represented internally using 4x4 homogeneous transformation matrices, allowing for chaining of operations.
Example
>>> with CoordinateTransformer() as t: ... t.translate(10.0, 0.0) ... t.rotate(90, axis = 'z') ... t.scale(2.0)
- apply_transform(point)
Transform a point using the current transformation matrix.
- chain_transform(transform_matrix)
Chain a new transformation with the current matrix.
- Parameters:
transform_matrix (ndarray) – A 4x4 transformation matrix to apply.
- Raises:
ValueError – If the input matrix is not 4x4.
- Return type:
None
- delete_state(name)
Delete a named transformation state.
- mirror(plane=Plane.ZX)
Apply a mirror transformation across a plane.
- Parameters:
- Raises:
ValueError – If the plane is not “xy”, “yz”, or “zx”.
- Return type:
None
- reflect(normal)
Apply a reflection transformation across a plane.
The reflection matrix is calculated using the Householder transformation: R = I - 2 * (n ⊗ n), where n is the normalized normal vector and ⊗ is outer product
- restore_state(name=None)
Restore the transformation state.
This reverts the transformation matrix and pivot point to the last saved state if no name is provided. If a name is given, it restores the transformation state associated with that name. This is useful for undoing temporary transformations or changes made after a
save_state()call.- Parameters:
name (str | None) – Optional name of the saved state to restore.
- Raises:
IndexError – If attempting to pop from an empty stack.
KeyError – If the named state does not exist.
- Return type:
None
- reverse_transform(point)
Invert a transformed point using the current matrix.
- rotate(angle, axis=Axis.Z)
Apply a rotation transformation around any axis.
- save_state(name=None)
Save the current transformation state.
This allows for temporary modifications to the transformation state, which can later be reverted using
restore_state(). The current transformation matrix and pivot point are saved on the stack if a name is not provided, otherwise the state is saved with that name for later retrieval.- Parameters:
name (str | None) – Optional name for the saved state
- Return type:
None
- scale(*scale)
Apply uniform or non-uniform scaling to axes.
- Parameters:
*scale (float) – Scale factors for the axes.
- Return type:
None
Example
>>> matrix.scale(2.0) # Scale everything by 2x >>> matrix.scale(2.0, 0.5) # Stretch in x, compress in y >>> matrix.scale(2.0, 1.0, 0.5) # Stretch x, preserve y, compress z
- Raises:
ValueError – If number of scale factors is not between 1 and 3.
- Parameters:
scale (float)
- Return type:
None
- set_pivot(point)
Set the pivot point for subsequent transformations.
The pivot point is the reference around which transformations like rotation and scaling occur. For example, to rotate a circle around its center, set the pivot point to the circle’s midpoint before applying the rotation. By default it is set to the origin of coordinates.
- class gscrib.geometry.PathTracer(builder)
Bases:
objectGenerating G-code with interpolated motion paths.
This class provides methods to generate G-code commands for complex motion paths by approximating them with small linear segments. The path approximation resolution can be configured to balance between motion smoothness and G-code file size. Smaller resolution values result in smoother paths but generate more G-code commands.
Unlike standard G-code where arc movements are affected by the selected plane (G17/G18/G19), this class always traces paths on the XY plane by default. To transform paths to other planes or orientations, use the transformation methods provided by the builder (translate, rotate, scale, etc).
For complex transformations, the
GCodeCore.transformproperty can be used as a context manager to ensure proper matrix stack handling. Transformations can be combined and will affect all subsequent path operations until the context is exited.Example
>>> g.move(x=10, y=0) # Move to start position >>> g.set_resolution(0.1) # Set 0.1mm resolution >>> g.set_direction("cw") # Set clockwise direction >>> >>> # Draw a quarter circle in XY plane >>> g.trace.arc(target=(0, 10), center=(-10, 0)) >>> >>> # Draw an arc rotated 45° around the X axis >>> with g.current_transform(): # Save current transform ... g.move(x=0, y=0) ... g.transform.rotate(45, 'x') # Rotate 45° around X axis ... g.trace.circle(center=(0, 10)) ... # Applied transforms are restored here
- arc(target, center, **kwargs)
Trace an arc from the current position to a target point.
This method generates a series of linear segments that approximate a circular arc. The arc is traced around a center point, maintaining a constant radius throughout the motion.
The direction of the arc is determined by the last call to set_direction(). If Z is provided for the target point, the arc will perform helical interpolation.
- Parameters:
- Raises:
ValueError – If start and end points are not equidistant
- Return type:
None
Example
>>> # Draw a quarter circle (90 degrees) clockwise >>> g.move(x=0, y=10) >>> g.set_direction("cw") # clockwise >>> g.trace.arc(target=(10, 0), center=(0, -10))
- arc_radius(target, radius, **kwargs)
Trace an arc to target point with specified radius.
Creates an arc from the current position to the target point with the specified radius. Similar to G2/G3 commands, if the radius is positive, the shorter arc will be traced. When negative, the longer arc will be traced.
The direction of the arc is determined by the last call to set_direction(). If Z is provided for the target point, the arc will perform helical interpolation.
- Parameters:
- Raises:
ValueError – If radius is too small for the given points
- Return type:
None
Example
>>> # Draw a quarter circle with 10mm radius (shorter arc) >>> g.move(x=0, y=0) >>> g.trace.arc_radius(target=(10, 10), radius=10) >>> >>> # Draw the longer arc between the same points >>> g.move(x=0, y=0) >>> g.trace.arc_radius(target=(10, 10), radius=-10)
- circle(center, **kwargs)
Trace a complete circle around a center point.
Creates a full 360-degree circular path around the specified center point, starting and ending at the current position. The direction of rotation is determined by the last call to set_direction().
- Parameters:
center (Point) – Center point (x, y) relative to the current position
**kwargs – Additional G-code parameters (added to each move)
- Return type:
None
Example
>>> # Draw a circle with 10mm radius >>> g.move(x=10, y=0) >>> g.set_direction("ccw") # counter-clockwise >>> g.trace.circle(center=(-10, 0))
- estimate_length(samples, function)
Estimate the total length of a parametric curve.
Calculates an approximation of the curve length by sampling points along the curve and summing the distances between consecutive points. The accuracy of the estimation improves with a higher number of samples, but requires more computation time.
- helix(target, center, turns=1, **kwargs)
Trace a helical path to target point with varying radius.
Creates a helical motion that can change radius as it moves from the current position to the target point. The motion is defined by a center point and the number of complete revolutions.
- Parameters:
- Raises:
ValueError – If turns is not positive
- Return type:
None
Example
>>> # Create a spiral with 3 turns >>> g.move(x=10, y=0) >>> g.trace.helix(target=(5, 0), center=(-10, 0), turns=3) >>> >>> # Create a helix up 10mm with 2 turns >>> g.move(x=10, y=0) >>> g.trace.helix(target=(10, 0, 10), center=(-10, 0), turns=2)
- parametric(function, length, **kwargs)
Approximate a parametric curve with linear segments.
Divides a parametric curve into small linear segments based on the current resolution setting. The curve is traced using G1(linear) movements to create a linear approximation of the desired path.
The curve is defined by a parametric function that maps an array of theta parameters in the range [0, 1] to points in space. The number of segments is calculated from the provided curve length and current resolution setting.
- Parameters:
function (PathFn) – Parametric function f(theta)
length (float) – Total curve length in current work units
**kwargs – Additional G-code parameters (added to each move)
- Raises:
ValueError – If the length parameter is not positive.
- Return type:
None
Example
>>> def circle(thetas: ndarray) -> ndarray: ... x = 10 * cos(2 * pi * thetas) ... y = 10 * sin(2 * pi * thetas) ... z = zeros(thetas.shape) ... return column_stack((x, y, z)) >>> >>> length = g.trace.estimate_length(100, circle) >>> g.trace.parametric(circle, length)
- polyline(targets, **kwargs)
Trace straight lines through the given points.
Creates a series of straight lines connecting all the specified points, starting from the current position.
- Parameters:
targets (Sequence[Point]) – Sequence of control points (x, y, [z])
**kwargs – Additional G-code parameters (added to each move)
- Raises:
ValueError – If not enought points are provided
- Return type:
None
- spiral(target, turns=1, **kwargs)
Trace a spiral path from current position to target point.
Creates a spiral motion that changes radius as it moves from the current position to the target point. If Z is provided for the target point, the spiral will perform helical interpolation.
- Parameters:
- Raises:
ValueError – If turns is not positive
- Return type:
None
- spline(targets, **kwargs)
Trace a cubic spline through the given control points.
Creates a smooth curve that passes through all the specified control points, starting from the current position. The spline is approximated using linear segments based on the current resolution setting.
- Parameters:
targets (Sequence[Point]) – Sequence of control points (x, y, [z])
**kwargs – Additional G-code parameters (added to each move)
- Raises:
ValueError – If not enought points are provided
- Return type:
None
Example
>>> # Draw a smooth curve through three points >>> g.trace.spline([(5, 5), (10, -5), (15, 0)])
- thread(target, pitch=1, **kwargs)
Trace a thread-like helical path to target point.
Creates a helical motion with constant radius from the current position to the target point. The motion is defined by the distance from the current position to the target Z height and the pitch.
- Parameters:
- Raises:
ValueError – If radius or pitch is not positive
- Return type:
None
- class gscrib.geometry.Point(x=None, y=None, z=None)
Bases:
NamedTupleA point in a 3D space.
This class represents a point in 3D space, where each coordinate (x, y, z) can be either a
floatvalue orNone. None values indicate unknown or unspecified coordinates.Most methods in
gscrib.GCodeCoreandgscrib.GCodeBuilderthat acceptPointobjects are designed to work with point-like values, which can be aPointobject or a sequence containing the (x, y, z) coordinates as numeric values.The class supports basic arithmetic operations, that raise
TypeErrorif any coordinates of the points are unknown. The methodresolvecan be used to create a newPointwith any unknown coordinates set to zero.Examples
>>> #Create points using different constructors: >>> p1 = Point(1.0, 2.0, 3.0) # All coordinates specified >>> p2 = Point(x=1.0, z=3.0) # Y coordinate is None >>> p3 = Point.zero() # Point at origin (0, 0, 0) >>> p4 = Point.unknown() # All coordinates are None >>> >>> # Using PointLike values >>> g.move([1.0, 2.0, 3.0]) # Using a list >>> g.move(point=(1.0, 2.0, 3.0)) # Using a tuple >>> g.move(Point(1.0, 2.0, 3.0)) # Using a Point object >>> g.move(x=1.0, y=2.0, z=3.0) # Individual coordinates >>> >>> # Arithmetic operations >>> p1 = Point(1.0, 2.0, 3.0) >>> p2 = Point(2.0, 3.0, 4.0) >>> p3 = p1 + p2 # Point(3.0, 5.0, 7.0) >>> p4 = p2 - p1 # Point(1.0, 1.0, 1.0) >>> p5 = p1 * 2 # Point(2.0, 4.0, 6.0) >>> p6 = p1 / 2 # Point(0.5, 1.0, 1.5)
- classmethod from_params(params)
Create a point from a dictionary of move parameters.
- Parameters:
params (ParamsDict)
- Return type:
- classmethod from_vector(vector)
Create a Point from a 4D vector
- Parameters:
vector (ndarray)
- Return type:
- combine(o, t, m)
Update coordinates based on position changes.
Updates coordinates by comparing the current, reference, and target points. Individual coordinates are updated to the values from point ‘m’ following these rules:
If the current coordinate is not None.
If current is None but reference and target differ.
- count(value, /)
Return number of occurrences of value.
- index(value, start=0, stop=9223372036854775807, /)
Return first index of value.
Raises ValueError if the value is not present.
- mask(x=None, y=None, z=None)
Create a new point with coordinates set to None if specified.
This method creates a new point where coordinates are set to
Noneif their corresponding parameter is notNone. This is useful for marking coordinates as unknown when they are involved in an operation.
- replace(x=None, y=None, z=None)
Create a new point replacing only the specified coordinates.
- to_vector()
Convert point to a 4D vector
- Return type:
ndarray
- within_bounds(min_point, max_point)
Check if point lies within bounds defined by two points.
Coordinates that are
Nonein either self, min_point, or max_point points are ignored in the comparison.