otaf.geometry package

Module contents

otaf.geometry.angle_between_planes(normal1, normal2)[source]

Calculate the angle between two planes.

Parameters:
  • normal1 (numpy.ndarray) – A 1D NumPy array representing the normal vector of the first plane.

  • normal2 (numpy.ndarray) – A 1D NumPy array representing the normal vector of the second plane.

Returns:

The angle between the planes in radians.

Return type:

float

Notes

  • The angle is calculated using the dot product of the normal vectors.

otaf.geometry.angle_between_vectors(vec1, vec2, assume_normalized=False)[source]

Calculate the angle in radians between two vectors.

Parameters:
  • vec1 (numpy.ndarray) – A 1D NumPy array representing the first vector.

  • vec2 (numpy.ndarray) – A 1D NumPy array representing the second vector.

  • assume_normalized (bool, optional) – If True, assumes the input vectors are already normalized, skipping normalization (default is False).

Returns:

The angle between vec1 and vec2 in radians.

Return type:

float

Raises:

ValueError – If one or both vectors have zero or near-zero magnitude, making the angle undefined.

Notes

  • The angle is computed using the dot product formula: cos(theta) = (vec1 . vec2) / (||vec1|| * ||vec2||).

  • The result is clamped to the range [-1, 1] to account for floating-point inaccuracies.

otaf.geometry.are_normals_aligned_and_facing(normal1, point1, normal2, point2, atol=1e-09)[source]

Check if two normal vectors are aligned in opposite directions and facing each other.

Vectors are considered to be facing each other if they are approximately anti-parallel (opposed) and the points from which they originate are positioned such that their extensions would intersect.

Parameters:
  • normal1 (numpy.ndarray) – A 1D NumPy array representing the first normal vector.

  • point1 (numpy.ndarray) – A 1D NumPy array representing the origin of the first normal vector.

  • normal2 (numpy.ndarray) – A 1D NumPy array representing the second normal vector.

  • point2 (numpy.ndarray) – A 1D NumPy array representing the origin of the second normal vector.

  • atol (float, optional) – Absolute tolerance for considering the normals to be facing each other (default is 1e-9).

Returns:

True if the normals are opposed and facing each other, False otherwise.

Return type:

bool

Notes

  • This function checks that the dot product of the normals is approximately -1 (indicating they are anti-parallel).

  • The vectors from point1 to point2 are used to ensure the normals are facing each other.

otaf.geometry.are_planes_coincident(normal1, point1, normal2, point2, tolerance=1e-08)[source]

Check if two planes are coincident within a specified tolerance.

Parameters:
  • normal1 (numpy.ndarray) – A 1D NumPy array representing the normal vector of the first plane.

  • point1 (numpy.ndarray) – A 1D NumPy array representing a point on the first plane.

  • normal2 (numpy.ndarray) – A 1D NumPy array representing the normal vector of the second plane.

  • point2 (numpy.ndarray) – A 1D NumPy array representing a point on the second plane.

  • tolerance (float, optional) – The tolerance within which the planes are considered coincident (default is 1e-8).

Returns:

True if the planes are coincident within the specified tolerance, False otherwise.

Return type:

bool

Notes

  • Two planes are considered coincident if their normal vectors are parallel (same or opposite direction) and the distance between the planes is within the specified tolerance.

otaf.geometry.are_planes_facing(normal1, point1, normal2, point2, atol=1e-09, max_angle=0.26)[source]

Check if translating the origin of each plane along its normal intersects the other plane.

This method determines whether the planes are “facing” each other, meaning their normals are approximately opposite, and translation along the normal of one plane intersects the other.

Parameters:
  • normal1 (numpy.ndarray) – A 1D NumPy array representing the normal vector of the first plane.

  • point1 (numpy.ndarray) – A 1D NumPy array representing a point on the first plane.

  • normal2 (numpy.ndarray) – A 1D NumPy array representing the normal vector of the second plane.

  • point2 (numpy.ndarray) – A 1D NumPy array representing a point on the second plane.

  • atol (float, optional) – Absolute tolerance for the intersection check (default is 1e-9).

  • max_angle (float, optional) – Maximum allowed deviation from π radians (180°) for the planes to be considered facing (default is 0.26).

Returns:

True if the planes are facing each other and the translated origins intersect, False otherwise.

Return type:

bool

Notes

  • The method uses the angle between the normals to determine alignment and checks the position of the points relative to each plane.

  • The max_angle parameter controls the angular tolerance, approximately ±15° by default.

  • If the plains are coincident and the angle between the normal is OK they are assumed facing

otaf.geometry.are_planes_parallel(normal1, normal2, tolerance=1e-08)[source]

Check if two planes are parallel within a specified tolerance.

Parameters:
  • normal1 (numpy.ndarray) – A 1D NumPy array representing the normal vector of the first plane.

  • normal2 (numpy.ndarray) – A 1D NumPy array representing the normal vector of the second plane.

  • tolerance (float, optional) – The tolerance within which the planes are considered parallel (default is 1e-8).

Returns:

True if the planes are parallel within the specified tolerance, False otherwise.

Return type:

bool

Notes

  • Two planes are parallel if the dot product of their normal vectors is approximately ±1.

otaf.geometry.are_planes_perpendicular(normal1, normal2, tolerance=1e-08)[source]

Check if two planes are perpendicular within a specified tolerance.

Parameters:
  • normal1 (numpy.ndarray) – A 1D NumPy array representing the normal vector of the first plane.

  • normal2 (numpy.ndarray) – A 1D NumPy array representing the normal vector of the second plane.

  • tolerance (float, optional) – The tolerance within which the planes are considered perpendicular (default is 1e-8).

Returns:

True if the planes are perpendicular within the specified tolerance, False otherwise.

Return type:

bool

Notes

  • Two planes are perpendicular if the dot product of their normal vectors is approximately 0.

otaf.geometry.are_points_on_2d_plane(points, return_normal=False)[source]

Check if all points lie on the same 2D plane.

Parameters:
  • points (numpy.ndarray) – A 2D NumPy array of shape (N, D), where N is the number of points and D is the dimension.

  • return_normal (bool, optional) – If True, returns the normal vector of the plane in addition to the boolean result (default is False).

Returns:

  • A boolean indicating whether all points lie on the same 2D plane.

  • If return_normal is True, also returns the normal vector of the plane.

Return type:

Union[Tuple[bool, numpy.ndarray], bool]

Raises:

ValueError – If fewer than 3 points are provided.

Notes

  • The method determines coplanarity by computing the normal vector of the plane formed by the first three points and checking if all other points lie on that plane.

otaf.geometry.calculate_cylinder_surface_frame(axis_translation, axis_rotation, radius, use_interior_normal=False)[source]

Calculate a transformation matrix to position a frame on a cylinder’s surface.

The transformation positions a frame on the cylinder surface based on a specified displacement along the axis, a rotation angle around the axis, and the cylinder radius.

Parameters:
  • axis_translation (float) – The displacement along the cylinder’s axis.

  • axis_rotation (float) – The rotation angle around the axis, in radians.

  • radius (float) – The radius of the cylinder.

  • use_interior_normal (bool, optional) – If True, the normal points inward toward the cylinder’s axis. If False, the normal points outward (default is False).

Returns:

A 4x4 transformation matrix for positioning a frame on the cylinder’s surface.

Return type:

numpy.ndarray

Raises:

ValueError – If the radius is negative or the rotation angle is outside the range -2π to 2π.

Notes

  • The transformation includes translations and rotations to align the frame with the cylinder’s geometry.

  • The direction of the normal vector can be controlled using the use_interior_normal parameter.

otaf.geometry.calculate_scalar_projection_factor(vector_to_project, reference_vector)[source]

Calculate the scalar projection factor of one vector onto another.

The scalar projection factor represents the length of the projection of one vector onto another, divided by the length of the reference vector.

Parameters:
  • vector_to_project (numpy.ndarray) – A 1D NumPy array representing the vector to be projected.

  • reference_vector (numpy.ndarray) – A 1D NumPy array representing the reference vector onto which the first vector is projected.

Returns:

The scalar projection factor.

Return type:

float

Notes

  • The scalar projection factor is calculated as the dot product of the two vectors divided by the squared norm of the reference vector.

otaf.geometry.centroid(arr)[source]

Calculate the centroid of a set of points.

Parameters:

arr (numpy.ndarray) – A 2D NumPy array where each row represents a point.

Returns:

A 1D NumPy array representing the centroid of the points.

Return type:

numpy.ndarray

Notes

  • The centroid is calculated as the mean of all points along each axis.

otaf.geometry.closest_point_on_line(line_point1, line_point2, point)[source]

Find the closest point on a line segment to a given point.

Parameters:
  • line_point1 (numpy.ndarray) – A 1D NumPy array representing one endpoint of the line segment.

  • line_point2 (numpy.ndarray) – A 1D NumPy array representing the other endpoint of the line segment.

  • point (numpy.ndarray) – A 1D NumPy array representing the point to find the closest point for.

Returns:

A 1D NumPy array representing the closest point on the line segment to the given point.

Return type:

numpy.ndarray

Notes

  • The closest point is computed using vector projections.

otaf.geometry.closest_point_on_plane(plane_normal, plane_point, point)[source]

Find the closest point on a plane to a given point.

Parameters:
  • plane_normal (numpy.ndarray) – A 1D NumPy array representing the normal vector of the plane.

  • plane_point (numpy.ndarray) – A 1D NumPy array representing a point on the plane.

  • point (numpy.ndarray) – A 1D NumPy array representing the point to find the closest point for.

Returns:

A 1D NumPy array representing the closest point on the plane to the given point.

Return type:

numpy.ndarray

Notes

  • The closest point is determined by projecting the input point onto the plane.

otaf.geometry.compute_bounding_box(points)[source]

Compute the bounding box for a set of multi-dimensional points.

The bounding box is defined by the minimum and maximum values along each dimension.

Parameters:

points (numpy.ndarray) – A 2D NumPy array of shape (N, M), where N is the number of points and M is the dimensionality.

Returns:

A 2D NumPy array of shape (M, 2), where each row represents [min, max] values for a dimension.

Return type:

numpy.ndarray

Notes

  • The bounding box is calculated independently for each dimension of the input points.

otaf.geometry.distance_between_planes(normal1, point1, normal2, point2)[source]

Calculate the distance between two parallel planes.

Parameters:
  • normal1 (numpy.ndarray) – A 1D NumPy array representing the normal vector of the first plane.

  • point1 (numpy.ndarray) – A 1D NumPy array representing a point on the first plane.

  • normal2 (numpy.ndarray) – A 1D NumPy array representing the normal vector of the second plane.

  • point2 (numpy.ndarray) – A 1D NumPy array representing a point on the second plane.

Returns:

The distance between the two planes. Returns 0.0 if the planes are not parallel (i.e., they intersect).

Return type:

float

Notes

  • The distance is computed only if the planes are parallel.

  • For intersecting planes, the distance is considered 0.

otaf.geometry.do_bounding_boxes_overlap(bbox1, bbox2)[source]

Check if two multidimensional bounding boxes overlap.

Parameters:
  • bbox1 (numpy.ndarray) – A 2D NumPy array of shape (M, 2), where each row represents [min, max] values for a dimension.

  • bbox2 (numpy.ndarray) – A 2D NumPy array of shape (M, 2), where each row represents [min, max] values for a dimension.

Returns:

True if the bounding boxes overlap, False otherwise.

Return type:

bool

Notes

  • Bounding boxes overlap if their intervals intersect in all dimensions.

otaf.geometry.euclidean_distance(point1, point2)[source]

Compute the Euclidean distance between two points.

Parameters:
  • point1 (numpy.ndarray) – A 1D NumPy array representing the first point.

  • point2 (numpy.ndarray) – A 1D NumPy array representing the second point.

Returns:

The Euclidean distance between point1 and point2.

Return type:

float

Notes

  • The Euclidean distance is calculated as the L2 norm of the difference between the points.

otaf.geometry.generate_circle_points(radius, num_points, center=(0, 0), start_angle=0, rnd=9)[source]

Generate points evenly distributed around a circle in 2D space.

Parameters:
  • radius (float or int) – The radius of the circle.

  • num_points (int) – The number of points to generate.

  • center (Iterable[Union[float, int]], optional) – The (x, y) coordinates of the circle’s center (default is (0, 0)).

  • start_angle (float or int, optional) – The starting angle in degrees, where 0 degrees is along the positive x-axis (default is 0).

  • rnd (int, optional) – Number of decimal places to round the output points (default is 9).

Returns:

A NumPy array of shape (num_points, 2), where each row represents an (x, y) point on the circle.

Return type:

numpy.ndarray

Notes

  • The points are evenly distributed along the circle’s circumference.

  • The starting angle allows customization of the initial point’s position relative to the x-axis.

otaf.geometry.generate_circle_points_3d(radius, num_points, center=(0, 0, 0), normal=(0, 0, 1), start_angle=0)[source]

Generate points evenly distributed around a circle in 3D space.

Parameters:
  • radius (float or int) – The radius of the circle.

  • num_points (int) – The number of points to generate.

  • center (Iterable[Union[float, int]], optional) – The (x, y, z) coordinates of the circle’s center (default is (0, 0, 0)).

  • normal (Iterable[Union[float, int]], optional) – The normal vector defining the plane of the circle (default is (0, 0, 1)).

  • start_angle (float or int, optional) – The starting angle in degrees, where 0 degrees is along the positive x-axis (default is 0).

Returns:

A NumPy array of shape (num_points, 3), where each row represents an (x, y, z) point on the circle.

Return type:

numpy.ndarray

Notes

  • The circle is initially generated in the XY-plane and then rotated to align with the specified normal vector.

  • The starting angle allows customization of the initial point’s position relative to the x-axis in the circle’s plane.

otaf.geometry.is_affine_transformation_matrix(M, raise_exception=False)[source]

Check if a 4x4 matrix is a valid affine transformation matrix with a valid rotation component.

An affine transformation matrix must meet the following criteria: - It is a 4x4 matrix. - Its last row is [0, 0, 0, 1]. - The top-left 3x3 submatrix is a valid rotation matrix (orthonormal and determinant equals 1).

Parameters:
  • M (numpy.ndarray) – A 4x4 NumPy array representing the matrix to be checked.

  • raise_exception (bool, optional) – If True, raises an exception when the matrix is invalid. If False, returns False instead (default is False).

Returns:

True if the matrix is an affine transformation matrix, False otherwise.

Return type:

bool

Raises:

otaf.exceptions.InvalidAffineTransformException – If the matrix is not a valid affine transformation matrix and raise_exception is True.

Notes

  • The validity of the rotation matrix is checked using orthonormality and determinant conditions.

otaf.geometry.is_bounding_box_within(bbox1, bbox2)[source]

Check if one bounding box is completely contained within another.

Parameters:
  • bbox1 (numpy.ndarray) – A 2D NumPy array of shape (M, 2), representing the first bounding box. Each row represents [min, max] values for a dimension.

  • bbox2 (numpy.ndarray) – A 2D NumPy array of shape (M, 2), representing the second bounding box. Each row represents [min, max] values for a dimension.

Returns:

True if bbox1 is completely within bbox2, False otherwise.

Return type:

bool

Notes

  • This function checks that the minimum values of bbox1 are greater than or equal to the minimum values of bbox2 and that the maximum values of bbox1 are less than or equal to the maximum values of bbox2.

otaf.geometry.line_plane_intersection(plane_normal, plane_point, line_point, line_direction)[source]

Compute the intersection point of a line and a plane.

Parameters:
  • plane_normal (numpy.ndarray) – A 1D NumPy array representing the normal vector of the plane.

  • plane_point (numpy.ndarray) – A 1D NumPy array representing a point on the plane.

  • line_point (numpy.ndarray) – A 1D NumPy array representing a point on the line.

  • line_direction (numpy.ndarray) – A 1D NumPy array representing the direction vector of the line.

Returns:

A 1D NumPy array representing the intersection point of the line and the plane.

Return type:

numpy.ndarray

Raises:

ZeroDivisionError – If the line is parallel to the plane (i.e., the direction vector is orthogonal to the plane normal).

otaf.geometry.plane_parameters(point_on_plane, rotation_matrix)[source]

Compute the equation parameters of a plane given a point on the plane and a rotation matrix.

The plane equation is defined as Ax + By + Cz + D = 0, where: - A, B, and C are the components of the normal vector to the plane. - D is the distance to the plane along the normal vector.

Parameters:
  • point_on_plane (numpy.ndarray) – A 1D NumPy array representing a point on the plane.

  • rotation_matrix (numpy.ndarray) – A 3x3 rotation matrix representing the plane’s orientation in space.

Returns:

A tuple (A, B, C, D) representing the parameters of the plane equation.

Return type:

tuple

Notes

  • The normal vector is computed in the base frame using the rotation matrix.

  • The distance D is computed as the negative dot product of the normal vector and the point on the plane.

otaf.geometry.point_dict_to_arrays(point_dict)[source]

Convert a dictionary of points into separate arrays of labels and coordinates.

Parameters:

point_dict (dict) – A dictionary where keys are labels (str) and values are points (list, tuple, or numpy.ndarray).

Returns:

  • A 1D NumPy array of labels as strings.

  • A 2D NumPy array of points as floats.

Return type:

Tuple[numpy.ndarray, numpy.ndarray]

Raises:

Exception – If the conversion to arrays fails, the original exception is raised with additional context.

Notes

  • The labels are converted into a NumPy array of strings.

  • The points are stacked into a 2D NumPy array with dtype float64.

otaf.geometry.point_in_hull(point, hull)[source]

Determine if a point is inside a convex hull.

Parameters:
  • point (numpy.ndarray) – A 1D NumPy array representing the point to check.

  • hull (numpy.ndarray) – A 2D NumPy array representing the vertices of the convex hull.

Returns:

True if the point is inside the convex hull, False otherwise.

Return type:

bool

Notes

  • This function constructs a convex hull from the input points and the test point. If the hull volume does not change after adding the test point, the point is inside the hull.

otaf.geometry.point_plane_distance(plane_normal, plane_point, point)[source]

Calculate the shortest distance from a point to a plane.

Parameters:
  • plane_normal (numpy.ndarray) – A 1D NumPy array representing the normal vector of the plane.

  • plane_point (numpy.ndarray) – A 1D NumPy array representing a point on the plane.

  • point (numpy.ndarray) – A 1D NumPy array representing the point for which the distance is to be calculated.

Returns:

The shortest distance from the point to the plane.

Return type:

float

Notes

  • The distance is positive if the point lies above the plane and negative if below, relative to the plane’s normal vector.

otaf.geometry.point_to_segment_distance(point, segment_start, segment_end)[source]

Calculate the shortest distance from a point or array of points to a line segment.

Parameters:
  • point (numpy.ndarray) – A 1D or 2D NumPy array representing the point(s) to compute the distance for.

  • segment_start (numpy.ndarray) – A 1D NumPy array representing the start point of the line segment.

  • segment_end (numpy.ndarray) – A 1D NumPy array representing the end point of the line segment.

Returns:

The shortest distance from the point(s) to the line segment. Returns a float for a single point or a NumPy array for multiple points.

Return type:

Union[float, np.ndarray]

otaf.geometry.points_in_cylinder(pt1, pt2, r, q)[source]

Check if a point is inside a cylinder defined by two points and a radius.

The cylinder is defined by its axis (the line segment between pt1 and pt2) and its radius r. This function checks if the given point q lies inside this cylinder.

Parameters:
  • pt1 (numpy.ndarray) – A 1D NumPy array representing one endpoint of the cylinder’s axis.

  • pt2 (numpy.ndarray) – A 1D NumPy array representing the other endpoint of the cylinder’s axis.

  • r (float or int) – The radius of the cylinder.

  • q (numpy.ndarray) – A 1D NumPy array representing the point to be checked.

Returns:

True if the point q is inside the cylinder, False otherwise.

Return type:

bool

Notes

  • The check involves verifying that the point lies between pt1 and pt2 along the axis and that its perpendicular distance to the axis is less than or equal to the cylinder’s radius.

otaf.geometry.points_in_cylinder_vect(pt1, pt2, r, q)[source]

Check if multiple points are inside a cylinder defined by two points and a radius.

The cylinder is defined by its axis (the line segment between pt1 and pt2) and its radius r. This function checks for each point in q whether it lies inside this cylinder.

Parameters:
  • pt1 (numpy.ndarray) – A 1D NumPy array representing one endpoint of the cylinder’s axis.

  • pt2 (numpy.ndarray) – A 1D NumPy array representing the other endpoint of the cylinder’s axis.

  • r (float or int) – The radius of the cylinder.

  • q (numpy.ndarray) – A 2D NumPy array where each row represents a point to be checked.

Returns:

A 1D boolean NumPy array where each entry is True if the corresponding point in q is inside the cylinder, and False otherwise.

Return type:

numpy.ndarray

Notes

  • This function is vectorized to efficiently handle multiple points in q.

  • The check involves verifying that each point lies between pt1 and pt2 along the axis and that its perpendicular distance to the axis is less than or equal to the cylinder’s radius.

otaf.geometry.project_vector_onto_plane(vector, plane_normal)[source]

Project a vector onto a plane defined by its normal vector.

Parameters:
  • vector (numpy.ndarray) – A 1D NumPy array representing the vector to be projected.

  • plane_normal (numpy.ndarray) – A 1D NumPy array representing the normal vector of the plane.

Returns:

A 1D NumPy array representing the projection of the vector onto the plane.

Return type:

numpy.ndarray

Notes

  • The projection removes the component of the vector that is parallel to the plane normal.

otaf.geometry.rotation_matrix_from_vectors(vec1, vec2)[source]

Compute the rotation matrix that aligns vec1 to vec2.

This function returns a 3x3 rotation matrix that rotates vec1 to align it with vec2. It handles edge cases where the vectors are already aligned or opposite.

Parameters:
  • vec1 (array_like) – A 3-element array representing the source vector.

  • vec2 (array_like) – A 3-element array representing the target vector.

Returns:

A 3x3 rotation matrix that aligns vec1 with vec2.

Return type:

numpy.ndarray

Examples

>>> vec1 = [1, 0, 0]
>>> vec2 = [0, 1, 0]
>>> R = rotation_matrix_from_vectors(vec1, vec2)
>>> np.allclose(R @ vec1, vec2)
True
otaf.geometry.tfrt(*args)[source]

Alias for transformation_from_rotation_translation function.

otaf.geometry.transform_point(point, transformation_matrix)[source]

Transform a point using a given transformation matrix.

Parameters:
  • point (numpy.ndarray) – A 1D NumPy array representing the point to transform.

  • transformation_matrix (numpy.ndarray) – A 4x4 transformation matrix.

Returns:

A 1D NumPy array representing the transformed point.

Return type:

numpy.ndarray

Notes

  • The function assumes homogeneous coordinates for the transformation.

  • The transformation matrix must be a 4x4 affine matrix.