geom#
- class cryocat.utils.geom.Line(starting_point, line_dir)#
Bases:
object
- class cryocat.utils.geom.Matrix(input_data=None, size=3)#
Bases:
object- SE3_cleanup()#
Given an input matrix that is a rototranslation, perform some cleanup of rounding errors etc.
- Args:
input_matrix (_type_): _description_
- Returns:
_type_: _description_
- add_noise_and_project_to_so3(noise_level=0.05, degrees=False)#
Add noise to a matrix and project it back to SO(3) using SVD. (Singular value decomp.)
- cone_in_plane_decomp()#
Decomposes input rotation matrix into matrices cone, in_plane, where cone describes cone-rotation and in_plane describes in-plane-rotation.
It holds: rot_matrix == in_plane @ cone
- dual_basis_se3(index=None)#
Given an se(3)-matrix, return the ith coefficient of said matrix in linear combination w.r.t. canonical basis of se(3)
- Args:
i (int): 1,2,3,4,5 or 6 se_3 (_type_): se(3)-matrix
- Returns:
float: Coefficient from linear combination
- dual_basis_so3()#
Given a skew-symmetric 3x3 matric, return the coefficients of said matrix in linear combination w.r.t. canonical basis of so3
- Args:
so_3 (nd-array): so(3)-matrix
- in_plane_angle()#
- is_SE3()#
Boolean function to check whether an input matrix is a rototranslation.
- Args:
input_matrix (_type_): _description_
- Returns:
_type_: _description_
- is_SO3()#
Boolean function to check whether an input matrix is a rotation matrix.
- matrix_power(k)#
- special_euclidean_from_rot_translation(translation)#
Combine SO(3) matrix with R^3 translation to SE(3) matrix.
- Args:
rotation (np.array): SO(3) matrix translation (np.array): translation vector
- Returns:
np.array: SE(3) matrix
- twist_from_skew_translation(translation)#
Combine so(3) matrix with R^3 translation to se(3) matrix.
- Args:
skew_symm (np.array): so(3) matrix translation (np.array): translation vector
- Returns:
np.array: se(3) vector
- class cryocat.utils.geom.Point3D(x, y, z)#
Bases:
object- cone_indicator(cone_height, cone_radius, axis=None)#
Boolean function that checks whether a given point lies within a cone.
- Args:
input_point (numpy array): Point for which to check whether it lies in a cone cone_height (float): Height of the cone. cone_radius (float): Radius of the cone. axis (numpy array): Axis of revolution for cone. Defaults to -np.array([0,0,1]).
- Returns:
Bool: True if input_point lies in cone. False else.
- torus_indicator(inner_rad, outer_rad, axis=None)#
Boolean function that checks whether a given point lies within a solid torus.
- Args:
input_point (_type_): Point for which to check whether it lies in a solid torus. inner_rad (_type_): Inner radius of solid torus outer_rad (_type_): Outer radius of solid torus axis (_type_, optional): Axis of revolution. Tours lies in orthogonal complement of the axis. Defaults to np.array([0,0,1]).
- Returns:
Bool: True if input_point lies in solid torus. False else.
- torus_section_indicator(inner_rad, outer_rad, cone_radius, torus_revolution=None, cone_revolution=None)#
Boolean function that checks whether a given point lies in the intersection of a solid torus and a cone.
- Args:
input_point (_type_): Point for which to check whether it lies in the intersection. inner_rad (_type_): Inner radius of torus outer_rad (_type_): Outer radius of torus cone_radius (_type_): Radius of cone torus_revolution (_type_, optional): Axis of revolution of torus. Defaults to np.array([0,0,1]). cone_revolution (_type_, optional): Axis of revolution of cone. Defaults to np.array([1,0,0]).
- Returns:
Bool: _description_
- property x#
- property y#
- property z#
- class cryocat.utils.geom.Triangle(a, b, c)#
Bases:
object- area()#
- circumcircle()#
- circumcircle_radius()#
- inner_angles()#
- inscribed_circle()#
- cryocat.utils.geom.align_points_to_xy_plane(points_on_plane, plane_normal=None)#
Plane is rotated to be aligned with xy-plane.
- Parameters:
- points_on_planendarray
coplanar points
- plane_normalndarray, optional
Plane normal. Defaults to None. If None, plane normal is estimated from points_on_plane
- Returns:
- ndarray (n,3), ndarray (3,3)
Points in xy-plane, corresponding rotation matrix
- Raises:
- ValueError
One needs at least 3 points to specify a plane if plane normal is not given.
- cryocat.utils.geom.angle_between_n_vectors(v1, v2, degrees=True)#
Compute the angle (in degrees) between corresponding pairs of vectors in two arrays.
- Parameters:
- v1ndarray (n, d)
Each row represents d-dimensional vector.
- v2ndarray (n, d)
Each row represents d-dimensional vector.
- Returns:
- ndarray (n,)
Array containing the angles (in degrees) between corresponding vectors.
Examples
>>> import numpy as np >>> v1 = np.array([[1, 0, 0], [0, 1, 0]]) >>> v2 = np.array([[0, 1, 0], [1, 0, 0]]) >>> angle_between_n_vectors(v1, v2) array([90., 90.])
- cryocat.utils.geom.angle_between_vectors(vectors1, vectors2)#
Compute the angle (in degrees) between corresponding pairs of vectors in two arrays.
- Parameters:
- vectors1ndarray (n, d)
Each row represents a d-dimensional vector.
- vectors2ndarray (n, d)
Each row represents a d-dimensional vector.
- Returns:
- ndarray (n,)
Array containing the angles (in degrees) between corresponding vectors.
Examples
>>> vectors1 = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) >>> vectors2 = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]) >>> angle_between_vectors(vectors1, vectors2) array([90., 90., 90.])
- cryocat.utils.geom.angular_distance(input_rot1, input_rot2, convention='zxz', degrees=True, c_symmetry=1)#
Compute angular distance between two rotations. Formula is based on this post https://math.stackexchange.com/questions/90081/quaternion-distance
- Parameters:
- input_rot1scipy.spatial.transform.Rotation object
Rotation object describing orientation of particle.
- input_rot2scipy.spatial.transform.Rotation object
Rotation object describing orientation of particle.
- conventionstr, optional
Euler angle convention. Defaults to “zxz”.
- degreesbool, optional
Return angular distance in degrees (True) or radians (False). Defaults to True.
- c_symmetryint, optional
Rotational symmetry of underlying particles. Defaults to 1.
- Returns:
- float
Angular distance between input rotations.
Examples
>>> rot1 = srot.from_euler("zxz", [0, 0, 0], degrees=True) >>> rot2 = srot.from_euler("zxz", [45, 45, 0], degrees=True) >>> angular_distance(rot1, rot2) 45.0
- cryocat.utils.geom.angular_score_for_c_symmetry(inplane_1, inplane_2, c_symmetry, max_val=None)#
Computes an angular similarity score for arrays of in-plane angles, based on rotational symmetry.
- cryocat.utils.geom.area_triangle(coords)#
Calculate the area of a triangle given its vertex coordinates. See https://stackoverflow.com/questions/71346322/numpy-area-of-triangle-and-equation-of-a-plane-on-which-triangle-lies-on
- Parameters:
- coordsndarray
An array of shape (3, 3) where each row represents a vertex of the triangle, and each vertex is given by three coordinates (x, y, z).
- Returns:
- float
The area of the triangle.
Examples
>>> coords = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0]]) >>> area_triangle(coords) 0.5
- cryocat.utils.geom.cartesian_to_spherical(coord, normalize=True)#
Convert Cartesian coordinates to spherical coordinates.
- Parameters:
- coordnumpy.ndarray
A 2D array of shape (N, 3*K) where N is the number of points and K is the number of sets of 3D coordinates. Each set of 3D coordinates corresponds to a point in Cartesian space.
- normalizebool, optional
If True, the input Cartesian coordinates will be normalized before conversion. Default is True.
- Returns:
- phinumpy.ndarray
A 1D array of azimuthal angles (in radians) of shape (M,) where M is the number of valid points after filtering out NaNs.
- thetanumpy.ndarray
A 1D array of polar angles (in radians) of shape (M,) where M is the number of valid points after filtering out NaNs.
- Raises:
- ValueError
If the input
coorddoes not have the shape (N, 3*K).
Notes
The azimuthal angle phi is computed as the angle in the x-y plane from the positive x-axis, and the polar angle theta is computed from the positive z-axis. The function filters out any points that result in NaN values during the conversion process.
- cryocat.utils.geom.change_handedness_coordinates(coordinates, dimensions)#
The change_handedness_coordinates function takes in a pandas dataframe of coordinates and the dimensions of the coordinate system. It then changes the handedness of those coordinates by subtracting each z-coordinate from dimension[2]. This is done because we want to change our coordinate system so that it has its origin at the top left corner, with positive x going right and positive y going down. The original coordinate system had its origin at bottom left, with positive x going right and positive y going up.
- Parameters:
- coordinates
Store the coordinates of the voxels
- dimensions
Determine the new z value
- Returns:
- The coordinates with the z axis inverted
- Doc Author:
- Trelent
- cryocat.utils.geom.compare_rotations(angles1, angles2, c_symmetry=1, rotation_type='all')#
Compare the rotations between two sets of angles.
- Parameters:
- angles1list
The first set of angles.
- angles2list
The second set of angles.
- c_symmetryint
The degree of rotational symmetry. Defaults to 1.
- Returns:
- tuple
A tuple containing the following distances: - dist_degrees (float): The overall angular distance between the two sets of angles. - dist_degrees_normals (float): The angular distance between the normal vectors of the two sets of angles. - dist_degrees_inplane (float): The angular distance within the plane of rotation between the two sets of angles.
- cryocat.utils.geom.cone_distance(input_rot1, input_rot2)#
Compute great-circle distance between z-normals corresponding to orientations as represented by input rotations. This corresponds to angular distance between cone-rotation portions of respective input rotations.
- Parameters:
- input_rot1scipy.spatial.transform.Rotation object
Rotation object describing orientation of particle
- input_rot2scipy.spatial.transform.Rotation object
Rotation object describing orientation of particle
- Returns:
- float
cone-distance in degrees
- cryocat.utils.geom.cone_inplane_distance(input_rot1, input_rot2, convention='zxz', degrees=True, c_symmetry=1)#
Compute angular distance between cone-rotations and inplane-rotations, respectively.
- Parameters:
- input_rot1scipy.spatial.transform.Rotation object
Rotation object describing orientation of particle.
- input_rot2scipy.spatial.transform.Rotation object
Rotation object describing orientation of particle.
- conventionstr, optional
Euler angle convention. Defaults to “zxz”.
- degrees :bool, optional
Return angular distance in degrees (True) or radians (False). Defaults to True.
- c_symmetryint, optional
Rotational symmetry of underlying particles. Defaults to 1.
- Returns:
- float
Angular distance between cone-rotations
- float
angular distance between inplane rotations.
- cryocat.utils.geom.cube()#
- cryocat.utils.geom.distance_array(vol)#
- cryocat.utils.geom.dodecahedron()#
- cryocat.utils.geom.euler_angles_to_normals(angles)#
Compute normal vectors pointing in z-direction from Euler angles.
- Returns:
- ndarray (n,3)
Unit length z-normal vectors associated to input Euler angles.
- cryocat.utils.geom.fill_ellipsoid(box_size, ellipsoid_parameters)#
Fills a 3D space defined by
box_sizewith a boolean mask where an ellipsoid defined byellipsoid_parametersis located.- Parameters:
- box_sizeint or array_like
Size of the box in which the ellipsoid will be placed. If an integer is provided, it is interpreted as the size for all three dimensions. If a tuple or list is provided, it should contain three integers defining the dimensions of the box.
- ellipsoid_parametersarray_like
Coefficients for the general ellipsoid equation: Ax^2 + By^2 + Cz^2 + 2Dxy + 2Exz + 2Fyz + 2Gx + 2Hy + 2Iz + J = 0 Should contain ten elements corresponding to A, B, C, D, E, F, G, H, I, J respectively.
- Returns:
- numpy.ndarray
A 3D boolean array where True values represent the points inside or on the surface of the ellipsoid.
Examples
>>> box_size = 10 >>> ellipsoid_parameters = (1, 1, 1, 0, 0, 0, 0, 0, 0, -100) >>> mask = fill_ellipsoid(box_size, ellipsoid_parameters) >>> mask.shape (10, 10, 10)
- cryocat.utils.geom.fit_circle_2d_lsq(x, y, w=None)#
Fit a circle to 2D points using the least squares method. The method was taken from https://meshlogic.github.io/posts/jupyter/curve-fitting/fitting-a-circle-to-cluster-of-3d-points/
- Parameters:
- xarray_like
X-coordinates of the points.
- yarray_like
Y-coordinates of the points.
- warray_like, optional
Weights for each point. If provided, must be the same length as
xandy. Defaults to None.
- Returns:
- xcfloat
X-coordinate of the fitted circle’s center.
- ycfloat
Y-coordinate of the fitted circle’s center.
- rfloat
Radius of the fitted circle.
- errorfloat
Sum of the squared residuals of the fit.
Notes
This function fits a circle in 2D to a set of points (x, y) by solving the weighted least squares problem if weights
ware provided. If no weights are provided, it solves the ordinary least squares problem.Examples
>>> x = np.array([1, 2, 3]) >>> y = np.array([4, 5, 6]) >>> xc, yc, r, error = fit_circle_2d_lsq(x, y)
- cryocat.utils.geom.fit_circle_2d_newton(coord)#
Fit a circle to 2D data using Newton’s method.
- Parameters:
- coordndarray
An array of shape (N, 2) containing the x and y coordinates of the data points.
- Returns:
- circle_centerndarray
A 1D array containing the x and y coordinates of the circle’s center.
- circle_radiusfloat
The radius of the fitted circle.
- confidenceint
Confidence level of the fit, 1 if successful, -1 if the fit failed.
Notes
The function implements a numerical method to fit a circle to a set of 2D points by minimizing the algebraic distance to the circle. The method used is based on the algebraic form of a circle and Newton’s optimization method to find the circle parameters that best fit the data.
Examples
>>> points = np.array([[1, 2], [3, 4], [5, 6]]) >>> center, radius, conf = fit_circle_2d_newton(points) >>> print(center, radius, conf)
- cryocat.utils.geom.fit_circle_3d_lsq(coord)#
Fit a circle to 3D points using least squares optimization.
- Parameters:
- coordndarray
An array of shape (N, 3) containing the 3D coordinates of the points.
- Returns:
- circle_centerndarray
A 1D array of length 3 containing the x, y, z coordinates of the fitted circle’s center.
- circle_radiusfloat
The radius of the fitted circle.
- residual_errorfloat
Sum of the squared residuals of the fit.
Notes
This function projects 3D points onto a 2D plane that is normal to their average normal vector. It then fits a circle in 2D and transforms the center back to the 3D space.
- cryocat.utils.geom.fit_circle_3d_pratt(coord)#
Fit a circle to a set of 3D points using Pratt’s method after projecting them onto a 2D plane.
- Parameters:
- coordndarray
An array of shape (N, 3) containing N points in 3D space.
- Returns:
- circle_centerndarray
A 1D array of length 3 representing the center of the circle in 3D space.
- circle_radiusfloat
The radius of the fitted circle.
- confidenceint
Confidence indicator, returns 1 if the center is not at the origin, otherwise -1.
Notes
The function first projects the 3D points onto a 2D plane using a variance-based method. It then applies Pratt’s method to these 2D points to fit a circle. The center of the circle is then transformed back to 3D space. The radius is calculated as the mean Euclidean distance from the 3D points to the estimated center. The confidence is a simple check on the location of the center.
Examples
>>> points = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> center, radius, conf = fit_circle_3d_pratt(points) >>> print(center, radius, conf)
- cryocat.utils.geom.fit_circle_3d_taubin(coord)#
Fit a circle to 3D points using Taubin’s method projected onto a 2D plane.
- Parameters:
- coordndarray
An array of shape (N, 3) representing the coordinates of the 3D points.
- Returns:
- circle_centerndarray
A 1D array of length 3 representing the center of the fitted circle in 3D space.
- circle_radiusfloat
The radius of the fitted circle.
- confidencefloat
A confidence measure for the circle fitting. Returns -1 if the fitting fails.
Notes
The function projects 3D points onto a 2D plane using a variance-based method, then fits a circle in 2D using Newton’s method. The best fitting circle is selected based on the minimum radius criterion among possible circle fits.
Examples
>>> coord = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> center, radius, conf = fit_circle_3d_taubin(coord) >>> print(center, radius, conf)
- cryocat.utils.geom.fit_ellipsoid(coord)#
Fit an ellipsoid to a set of 3D coordinates. It is based on http://www.mathworks.com/matlabcentral/fileexchange/24693-ellipsoid-fit
- Parameters:
- coordndarray
An array of shape (N, 3) where each row represents the x, y, z coordinates.
- Returns:
- centerndarray
The center of the ellipsoid (x, y, z coordinates).
- radiindarray
Radii of the ellipsoid along the principal axes.
- evecsndarray
The eigenvectors corresponding to the principal axes of the ellipsoid.
- vndarray
The 1D array of the ellipsoid parameters used to form the quadratic form.
Notes
This function fits an ellipsoid to a set of points by solving a linear least squares problem to estimate the parameters of the ellipsoid’s equation in its algebraic form.
Examples
>>> points = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> center, radii, evecs, _ = fit_ellipsoid(points) >>> center array([x_center, y_center, z_center]) >>> radii array([radius_x, radius_y, radius_z]) >>> evecs array([[evec1_x, evec1_y, evec1_z], [evec2_x, evec2_y, evec2_z], [evec3_x, evec3_y, evec3_z]])
- cryocat.utils.geom.generate_angles(cone_angle, cone_sampling, inplane_angle=360.0, inplane_sampling=None, starting_angles=None, symmetry=1.0, angle_order='zxz')#
Compute Euler angles from sample for normal vectors on sphere. Sphere sample corresponds to cone-angles.
- Parameters:
- cone_anglefloat
Angle for sampling of cone-angles (refers to range of z-normals of particles).
- cone_samplingfloat
Frequency for cone sampling.
- inplane_anglefloat, optional
Desired inplane-angles for particle orientations. Defaults to 360.0.
- inplane_samplingfloat, optional
Frequency for sampling of inplane-angles. Defaults to None.
- starting_anglesndarray , optional
Triplet of Euler angles in convention as spefified by angle_order. Defaults to None.
- symmetryfloat, optional
Refers to rotational symmetry of particles. Defaults to 1.0.
- angle_orderstr, optional
Convention for Euler angles. Defaults to “zxz”.
- Returns:
- ndarray
Sample of Euler angles.
- cryocat.utils.geom.get_axis_from_rotation(input_rotation, axis='z')#
Given an input rotation, compute the desired unit normal vector from the coordinate frame associated to the rotation.
- Parameters:
- input_rotationscipy.spatial.transform.Rotation object
Rotation object describing orientation of particle
- axisstr, optional
Desired coordinate direction. Defaults to “z”.
- Returns:
- ndarray
unit vector
- Raises:
- ValueError
Input must be valid scipy rotation object.
- cryocat.utils.geom.great_circle_distance(p1, p2)#
- cryocat.utils.geom.great_circle_distance_matrix(points1, points2)#
Compute the pairwise great-circle distances between two sets of points on an n-sphere.
- cryocat.utils.geom.hausdorff_distance_sphere(set1, set2)#
Compute the simplified Hausdorff distance between two discrete sets of points on an n-sphere.
- cryocat.utils.geom.icosahedron()#
- cryocat.utils.geom.inplane_distance(input_rot1, input_rot2, convention='zxz', degrees=True, c_symmetry=1)#
Compute the angular distance between inplane-rotation portion of two given rotations.
- Parameters:
- input_rot1scipy.spatial.transform.Rotation object
Rotation object describing orientation of particle.
- input_rot2scipy.spatial.transform.Rotation object
Rotation object describing orientation of particle.
- conventionstr, optional
Euler angle convention. Defaults to “zxz”.
- degreesbool, optional
Return angular distance in degrees (True) or radians (False). Defaults to True.
- c_symmetryint, optional
Rotational symmetry of underlying particles. Defaults to 1.
- Returns:
- float
Angular distance between inplane rotations.
- cryocat.utils.geom.min_great_circle_distance(set1, set2)#
Computes the minimum great-circle distance between two sets of points on S^n.
- cryocat.utils.geom.n_gon_points(n)#
- cryocat.utils.geom.normalize_vector(vector)#
Normalize a vector.
- Parameters:
- vectorarray_like
Input vector to be normalized.
- Returns:
- ndarray
Normalized vector with the same direction but with a norm of 1.
Examples
>>> import numpy as np >>> v = np.array([2, 3, 6]) >>> normalize_vector(v) array([0.26726124, 0.40089186, 0.80278373])
- cryocat.utils.geom.normalize_vectors(v)#
Normalize each vector, handling both single vectors and arrays of vectors.
- Parameters:
- vndarray (n,d)
- Returns:
- ndarray (n,d)
Array of normalized vectors.
Examples
>>> import numpy as np >>> v = np.array([[1, 2, 3], [4, 5, 6]]) >>> normalize_vectors(v) array([[0.26726124, 0.53452248, 0.80178373],^ [0.45584231, 0.56980288, 0.68376346]])
- cryocat.utils.geom.normals_to_euler_angles(input_normals, output_order='zxz')#
Given normal vectors pointing in z-direction in particle frames, compute choice of Euler angles.
- Parameters:
- input_normalsndarray, pandas dataFrame
z-normal vectors
- output_orderstr, optional
Euler angle convention. Defaults to “zxz”.
- Returns:
- ndarray(n,3)
n triplets of Euler angles in choses convention.
- Raises:
- UserInputError
input_normals have to be either pandas dataFrame or numpy array.
- cryocat.utils.geom.number_of_cone_rotations(cone_angle, cone_sampling)#
Calculates the number of rotations required for a sampling process of cone-angles based on a sampling interval.
- Parameters:
- cone_anglefloat
The total cone-angle in degrees.
- cone_samplingfloat
The angular sampling interval in degrees.
- Returns:
- int
The total number of rotations required for the sampling process.
- cryocat.utils.geom.octahedron()#
- cryocat.utils.geom.order_points_on_circle(points)#
Order points on a circle based on their angles with respect to the x-axis.
- Parameters:
- pointsnumpy.ndarray
A 2D array of shape (n, 3) where each row represents a point in 3D space (x, y, z).
- Returns:
- numpy.ndarray
A 2D array of shape (n, 3) containing the input points ordered by their angles in the xy-plane, starting from the positive x-axis and moving counterclockwise.
- numpy.ndarray
A 1D array of shape (n,) containing the order of points.
Notes
This function assumes that the input points are approximately in the xy-plane, and it discards the z-coordinate for the ordering process. The points are normalized to lie on the unit circle before calculating their angles.
- cryocat.utils.geom.oversample_spline(coords, target_spacing)#
Fit a spline through 3D coordinates and oversample so that the distance between points is approximately
target_spacing.- Parameters:
- coordsndarray
Array of shape (n, 3) representing the input points.
- target_spacingfloat
Desired distance between points on the spline.
- Returns:
- ndarray
Oversampled coordinates along the spline.
- cryocat.utils.geom.point_ellipsoid_distance(p, params)#
Computes the shortest distance from a point p to the surface of an ellipsoid.
- cryocat.utils.geom.point_pairwise_dist(coord_1, coord_2)#
Calculate the pairwise Euclidean distance between two sets of coordinates.
- Parameters:
- coord_1ndarray
An array of shape (N, D) where N is the number of points and D is the dimensionality of each point. If N=1, the single point is broadcasted to match the number of points in coord_2.
- coord_2ndarray
An array of shape (M, D) where M is the number of points and D is the dimensionality of each point. If coord_1 has N>1, then M has to be equal to N.
- Returns:
- pairwise_distndarray
An array of shape (max(N, M),) containing the Euclidean distances between each pair of points from coord_1 and coord_2.
Notes
If the input arrays have complex numbers, the distance calculation defaults to 0.0 for those pairs.
- cryocat.utils.geom.project_3d_points_on_2d_plane_normal_aligned(coord, target_direction=None)#
Projects 3D points onto a 2D plane that is aligned with a specified normal direction.
- Parameters:
- coordndarray
An array of shape (N, 3) containing N points in 3D space.
- target_directionarray_like, optional
A 3-element array specifying the direction to which the normal of the 2D plane should be aligned. If None, defaults to [0, 0, 1], aligning the plane with the z-axis. Defaults to None.
- Returns:
- coord_projndarray
An array of shape (N, 2) containing the 2D coordinates of the projected points.
- coord_meanndarray
A 1D array of length 3 representing the mean of the original coordinates.
- normalndarray
A 1D array of length 3 representing the normal vector of the plane onto which the points are projected.
Notes
The function first centers the points by subtracting their mean. It then uses Singular Value Decomposition (SVD) to find the principal components of the points. The smallest singular vector (normal to the plane of best fit) is used. The points are then rotated to align this normal with the target direction, effectively projecting them onto a new 2D plane.
- cryocat.utils.geom.project_3d_points_on_2d_plane_variance_based(coord)#
Projects 3D points onto a 2D plane using variance-based method via Singular Value Decomposition (SVD).
- Parameters:
- coordndarray
An array of shape (N, 3) where n is the number of 3D points.
- Returns:
- coord_projndarray
The projected coordinates of the points onto the 2D plane, of shape (N, 2).
- Undarray
The matrix containing the left singular vectors of the decomposition, used to project the points.
Notes
The function performs dimensionality reduction by projecting the original 3D points onto the 2D plane that captures the most variance in the data. This is achieved using SVD, which decomposes the input matrix into its singular vectors and singular values.
Examples
>>> points = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> projected_points, _ = project_3d_points_on_2d_plane_variance_based(points) >>> print(projected_points)
- cryocat.utils.geom.project_points_on_plane_with_preserved_distance(starting_point, normal, nn_points)#
Project approximately coplanar points around a starting_point onto the plane perpendicular to normal vector. The distances between projected nearest neighbors and starting point are preserved.
- Parameters:
- starting_pointndarray
origin of plane specified by normal vector
- normalndarray
normal vector to plane
- nn_pointsndarray
nearest neighbors of starting_point
- Returns:
- ndarray
projected points on plane specified by starting_point and normal
- cryocat.utils.geom.quaternion_log(q)#
Given array of unit scalar-last quaternions, compute array of unit-quaternion logarithms.
- Parameters:
- qndarray (n,4)
Array of n unit quaternions in scalar-last convention.
- Returns:
- ndarray (n,4)
Array of n quaternion logarithms.
- cryocat.utils.geom.quaternion_mult(qs1, qs2)#
Given arrays of quaternions in scalar-last convention, compute array of products of unit quaternions.
- Parameters:
- qs1ndarray (n,4)
n quaternions in scalar-last convention.
- qs2ndarray (n,4)
n quaternions in scalar-last convention.
- Returns:
- ndarray (n,4)
n quaternions in scalar-last convention. Row i is product of qs1[i] and qs2[i].
- cryocat.utils.geom.ray_ellipsoid_intersection_3d(point, normal, ellipsoid_params)#
Compute the intersection between a ray starting at point in direction of normal and an ellipsoid specified by ellipsoid_params.
- Parameters:
- pointndarray (3,)
Point in 3D describing origin of ray.
- normalndarray (3,)
Normal vector describing direction of ray.
- ellipsoid_paramsndarray, list or tuple of 10 floats
Coefficients describing quadratic form of ellipsoid.
- Returns:
- tuple (p1, p2, d1, d2, is_inside) with:
p1: ndarray describing closest intersection, or NaN. p2: ndarray describing intersection, or NaN. d1: float (distance between point and p1), or NaN. d2: float (distance between point and p2), or NaN. is_inside: bool, true if point lies inside the ellipsoid.
- cryocat.utils.geom.ray_ray_intersection_3d(starting_points, ending_points)#
Calculate the intersection point and distances from the intersection to each line for a set of 3D rays.
- Parameters:
- starting_pointsndarray
An array of shape (N, 3) representing the starting points of N lines in 3D space.
- ending_pointsndarray
An array of shape (N, 3) representing the ending points of N lines in 3D space.
- Returns:
- P_intersectndarray
A 1D array of shape (3,) containing the coordinates of the intersection point.
- distancesndarray
A 1D array of shape (N,) containing the distances from the intersection point to each line.
Notes
This function assumes that all lines are somewhat close to intersecting at a common point and uses a least squares approach to find the best intersection point. The function may not be suitable for parallel lines or lines that do not converge.
- cryocat.utils.geom.rotate_points_rodrigues(P, n0, n1)#
Rotates points by the rotation defined by two vectors.
- Parameters:
- Pndarray
Array containing point(s) to be rotated. Can be a 1D array for a single point or a 2D array for multiple points.
- n0ndarray
Initial vector, before rotation. Must be a 1D array of 3 elements.
- n1ndarray
Final vector, after rotation. Must be a 1D array of 3 elements.
- Returns:
- P_rotndarray
Array of rotated points. Same shape as input array P.
Notes
This function computes the rotation matrix that rotates vector n0 to align with vector n1 and applies this rotation to point(s) P. The rotation is performed using the Rodrigues’ rotation formula, facilitated by scipy’s spatial transformations.
Examples
>>> P = np.array([1, 0, 0]) >>> n0 = np.array([1, 0, 0]) >>> n1 = np.array([0, 1, 0]) >>> rotate_points_rodrigues(P, n0, n1) array([[0., 1., 0.]])
- cryocat.utils.geom.sample_cone(cone_angle, cone_sampling, center=None, radius=1.0)#
Creates an “even” distibution on sphere. Works for tame cases. Source: https://stackoverflow.com/questions/9600801/evenly-distributing-n-points-on-a-sphere/26127012#26127012
- Parameters:
- cone_anglefloat
Angle for sampling of cone-angles (refers to range of z-normals of particles).
- cone_samplingfloat
Frequency for cone sampling.
- centerndarray, optional
Center of sphere to be sampled. Defaults to None.
- radiusfloat, optional
Radius of sphere to be sampled. Defaults to 1.0.
- Returns:
- ndarray
Samples on sphere.
- cryocat.utils.geom.spline_sampling(coords, sampling_distance)#
Samples a spline specified by coordinates with a given sampling distance
- Parameters:
- coordsndarray
coordinates of the spline
- sampling_distancefloat
sampling frequency in pixels
- Returns:
- ndarray
coordinates of points on the spline
- cryocat.utils.geom.tetrahedron()#
- cryocat.utils.geom.vector_angular_distance(v1, v2)#
Calculate the angular distance between two vectors in degrees.
- Parameters:
- v1array_like
First input vector.
- v2array_like
Second input vector.
- Returns:
- float
The angular distance between
v1andv2in degrees.
Examples
>>> v1 = [1, 0, 0] >>> v2 = [0, 1, 0] >>> vector_angular_distance(v1, v2) 90.0
- cryocat.utils.geom.vector_angular_distance_signed(u, v, n=None)#
Compute the signed angular distance between two vectors.
- Parameters:
- uarray_like
First input vector.
- varray_like
Second input vector.
- narray_like, optional
Normal vector to the plane containing
uandv. If not provided, the function computes the unsigned angular distance.
- Returns:
- float
The signed angular distance between vectors
uandv. This is the angle in radians between the two vectors, signed according to the direction given byn. Ifnis not provided, the result is the unsigned angle.
Notes
The signed angle is computed based on the right-hand rule. If
nis provided, the sign of the angle is determined by the direction ofnrelative to the cross product ofuandv. Ifnis not provided, the function returns the magnitude of the angle only.Examples
>>> u = np.array([1, 0, 0]) >>> v = np.array([0, 1, 0]) >>> vector_angular_distance_signed(u, v) 1.5707963267948966 # 90 degrees in radians
>>> n = np.array([0, 0, 1]) >>> vector_angular_distance_signed(u, v, n) 1.5707963267948966 # 90 degrees in radians, positive as per right-hand rule with `n` as z-axis
>>> n = np.array([0, 0, -1]) >>> vector_angular_distance_signed(u, v, n) -1.5707963267948966 # 90 degrees in radians, negative as per right-hand rule with `n` as -z-axis
- cryocat.utils.geom.visualize_angles(angles, plot_rotations=True, color_map=None)#
Compute z-normals of input orientations as described using Euler angles in zxz-convention. If desried, generate plot depicting z-normals of input orientations.
- Parameters:
- anglesndarray (n, 3)
Array of triplets of Euler angles in zxz-convention.
- plot_rotationsbool, optional
If True, plot is generated. Defaults to True.
- color_mapstr, optional
Specify colormap for plot. Defaults to None.
- Returns:
- ndarray (n,3)
Array of z-normals.
- cryocat.utils.geom.visualize_rotations(rotations, plot_rotations=True, color_map=None, marker_size=20, alpha=1.0, radius=1.0)#
Compute z-normals of input rotations. If desried, generate plot depicting z-normals of input rotations.
- Parameters:
- rotationsarray of scipy.spatial.transform.Rotation objects
Orientations to be visualized
- plot_rotationsbool, optional
If True, plot is generated. Defaults to True.
- color_mapstr, optional
Specify colormap for plot. Defaults to None.
- marker_sizeint, optional
Specify marker size for plot. Defaults to 20.
- alphafloat, optional
Specify alpha parameter for plot. Defaults to 1.0.
- radiusfloat, optional
Specify size of sphere for visualization. Defaults to 1.0.
- Returns:
- ndarray (n,3)
Array of z-normals.