From fb53b45ce3bd161499e1eed34d3cd0ba51f9450f Mon Sep 17 00:00:00 2001 From: Evan Harvey Date: Mon, 11 Nov 2024 16:43:38 -0700 Subject: [PATCH] opencsp/common/lib/geometry: test docs --- opencsp/common/lib/geometry/EdgeXY.py | 4 + opencsp/common/lib/geometry/Intersection.py | 207 +++++++++- opencsp/common/lib/geometry/TranslationXYZ.py | 36 ++ opencsp/common/lib/geometry/Uxy.py | 35 +- opencsp/common/lib/geometry/angle.py | 159 +++++++- opencsp/common/lib/geometry/geometry_2d.py | 384 +++++++++++++++++- opencsp/common/lib/geometry/geometry_3d.py | 261 +++++++++++- opencsp/common/lib/geometry/transform_3d.py | 84 +++- .../RenderControlIntersection.py | 27 ++ opencsp/test/test_DocStringsExist.py | 37 +- 10 files changed, 1185 insertions(+), 49 deletions(-) diff --git a/opencsp/common/lib/geometry/EdgeXY.py b/opencsp/common/lib/geometry/EdgeXY.py index 36acddaab..8b302982d 100644 --- a/opencsp/common/lib/geometry/EdgeXY.py +++ b/opencsp/common/lib/geometry/EdgeXY.py @@ -4,6 +4,10 @@ class EdgeXY: + """ + Representation of a 2D edge. + """ + def __init__(self, vertices: Vxy, curve_data: dict = {'type': 'line'}, closed: bool = False): """ Representation of a 2D edge. diff --git a/opencsp/common/lib/geometry/Intersection.py b/opencsp/common/lib/geometry/Intersection.py index 2870c3a48..546068ced 100644 --- a/opencsp/common/lib/geometry/Intersection.py +++ b/opencsp/common/lib/geometry/Intersection.py @@ -34,7 +34,23 @@ class Intersection: + """ + A class representing the intersection points of light paths with a plane. + + This class provides methods for calculating intersections of light paths with planes, + as well as utilities for managing and analyzing these intersection points. + """ + + # "ChatGPT 4o" assisted with generating this docstring. def __init__(self, intersection_points: Pxyz): + """Initializes the Intersection instance with the given intersection points. + + Parameters + ---------- + intersection_points : Pxyz + The intersection points to be stored in this instance. + """ + # "ChatGPT 4o" assisted with generating this docstring. self.intersection_points = intersection_points @classmethod @@ -48,8 +64,40 @@ def plane_intersect_from_ray_trace( max_ram_in_use_percent: float = 95.0, verbose: bool = False, ): - """Vectorized plane intersection algorithm - place = (plane_point, plane_normal_vector)""" + """ + Calculates intersection points of light paths with a specified plane. + + This method uses a vectorized algorithm to find where light paths intersect with a plane + defined by a point and a normal vector. + + Parameters + ---------- + ray_trace : RayTrace + The RayTrace object containing the light paths to be analyzed. + plane : tuple[Pxyz, Uxyz] + A tuple containing a point on the plane (Pxyz) and the normal vector to the plane (Uxyz). + epsilon : float, optional + A small value to determine the precision of the intersection calculation. Defaults to 1e-6. + save_in_file : bool, optional + If True, saves the intersection data to a file. Defaults to False. + save_name : str, optional + The name of the file to save the intersection data. Required if save_in_file is True. + max_ram_in_use_percent : float, optional + The maximum percentage of RAM to use for processing. Defaults to 95.0. + verbose : bool, optional + If True, enables verbose output for debugging purposes. Defaults to False. + + Returns + ------- + Intersection + An Intersection object containing the calculated intersection points. + + Raises + ------ + ValueError + If the intersection calculation fails or if the input parameters are invalid. + """ + # "ChatGPT 4o" assisted with generating this docstring. # Unpack plane plane_point, plane_normal_vector = plane @@ -139,27 +187,41 @@ def plane_lines_intersection( epsilon: float = 1e-6, verbose: bool = False, ) -> Pxyz: - """Vectorized plane intersection algorithm + """ + Calculates intersection points of multiple lines with a specified plane. + + This method determines where each line intersects with the plane defined by a point and a normal vector. Parameters ---------- lines : tuple[Pxyz, Vxyz] - The lines to find intersections for with the given plane. The lines - consist of two parts: a point (Pxyz) and a direction (Vxyz). Each - index in the points should correspond to the same index in the - directions. Note that only one Pxyz and Vxyz is needed to represent - multiple lines. + A tuple containing a point (Pxyz) and a direction vector (Vxyz) for the lines. Each + index in the points should correspond to the same index in the directions. Note that + only one Pxyz and Vxyz is needed to represent multiple lines. plane : tuple[Pxyz, Uxyz] - The plane to find the intersections of. The plane definition - consists of a point Pxyz that the plane goes through, and the normal - vector to the plane Uxyz. + A tuple containing a point on the plane (Pxyz) and the normal vector to the plane (Uxyz). + Each index in the points should correspond to the same index in the directions. Note that + only one Pxyz and Vxyz is needed to represent multiple lines. + epsilon : float, optional + A small value to determine the precision of the intersection calculation. Defaults to 1e-6. + verbose : bool, optional + If True, enables verbose output for debugging purposes. Defaults to False. Returns ------- - intersection_points: Pxyz - The intersection (x,y,z) locations for each of the lines with the plane, one per line. Shape (3,N), where N is the number of lines. - Disregards direction of line. + Pxyz + The intersection points (x, y, z) for each line with the plane. Shape (3, N), where N is the number of lines. + + Raises + ------ + ValueError + If the lines are parallel to the plane or if the input parameters are invalid. + + Notes + ----- + Disregards direction of line. """ + # "ChatGPT 4o" assisted with generating this docstring. # Unpack plane plane_point, plane_normal_vector = plane @@ -216,6 +278,22 @@ def plane_lines_intersection( @classmethod def from_hdf(cls, filename: str, intersection_name: str = "000"): + """ + Loads intersection points from an HDF5 file. + + Parameters + ---------- + filename : str + The path to the HDF5 file containing intersection data. + intersection_name : str, optional + The name of the intersection dataset to load. Defaults to "000". + + Returns + ------- + Intersection + An Intersection object containing the loaded intersection points. + """ + # "ChatGPT 4o" assisted with generating this docstring. # get the names of the batches to loop through intersection_points = Pxyz( list(load_hdf5_datasets([f"Intersection_{intersection_name}/Points"], filename).values())[0] @@ -224,6 +302,15 @@ def from_hdf(cls, filename: str, intersection_name: str = "000"): @classmethod def empty_intersection(cls): + """ + Creates an empty Intersection object. + + Returns + ------- + Intersection + An Intersection object with no intersection points. + """ + # "ChatGPT 4o" assisted with generating this docstring. return cls(Pxyz.empty()) def __add__(self, intersection: 'Intersection'): @@ -233,11 +320,31 @@ def __len__(self): return len(self.intersection_points) def save_to_hdf(self, hdf_filename: str, intersection_name: str = "000"): + """ + Saves the intersection points to an HDF5 file. + + Parameters + ---------- + hdf_filename : str + The path to the HDF5 file where the intersection data will be saved. + intersection_name : str, optional + The name of the intersection dataset to save. Defaults to "000". + """ + # "ChatGPT 4o" assisted with generating this docstring. datasets = [f"Intersection_{intersection_name}/Points", f"Intersection_{intersection_name}/Metatdata"] data = [self.intersection_points.data, "Placeholder"] save_hdf5_datasets(data, datasets, hdf_filename) def get_centroid(self) -> Pxyz: + """ + Calculates the centroid of the intersection points. + + Returns + ------- + Pxyz + The centroid of the intersection points as a Pxyz object. + """ + # "ChatGPT 4o" assisted with generating this docstring. N = len(self) x = sum(self.intersection_points.x) / N y = sum(self.intersection_points.y) / N @@ -247,14 +354,62 @@ def get_centroid(self) -> Pxyz: # flux maps def to_flux_mapXY(self, bins: int, resolution_type: str = None) -> FunctionXYGrid: + """ + Generates a flux map in the XY plane from the intersection points. + + Parameters + ---------- + bins : int + The number of bins to use for the histogram. + resolution_type : str, optional + The type of resolution to use for the flux map. Defaults to None. + + Returns + ------- + FunctionXYGrid + A FunctionXYGrid object representing the flux map in the XY plane. + """ + # "ChatGPT 4o" assisted with generating this docstring. pxy = Pxy([self.intersection_points.x, self.intersection_points.y]) return Intersection._Pxy_to_flux_map(pxy, bins, resolution_type) def to_flux_mapXZ(self, bins: int, resolution_type: str = None) -> FunctionXYGrid: + """ + Generates a flux map in the XZ plane from the intersection points. + + Parameters + ---------- + bins : int + The number of bins to use for the histogram. + resolution_type : str, optional + The type of resolution to use for the flux map. Defaults to None. + + Returns + ------- + FunctionXYGrid + A FunctionXYGrid object representing the flux map in the XZ plane. + """ + # "ChatGPT 4o" assisted with generating this docstring. pxz = Pxy([self.intersection_points.x, self.intersection_points.z]) return Intersection._Pxy_to_flux_map(pxz, bins, resolution_type) def to_flux_mapYZ(self, bins: int, resolution_type: str = None) -> FunctionXYGrid: + """ + Generates a flux map in the YZ plane from the intersection points. + + Parameters + ---------- + bins : int + The number of bins to use for the histogram. + resolution_type : str, optional + The type of resolution to use for the flux map. Defaults to None. + + Returns + ------- + FunctionXYGrid + A FunctionXYGrid object representing the flux map in the YZ plane. + """ + # "ChatGPT 4o" assisted with generating this docstring. pyz = Pxy([self.intersection_points.y, self.intersection_points.z]) return Intersection._Pxy_to_flux_map(pyz, bins, resolution_type) @@ -282,11 +437,35 @@ def _Pxy_to_flux_map(points: Pxy, bins: int, resolution_type: str = "pixelX") -> # drawing def draw(self, view: View3d, style: RenderControlPointSeq = None): + """ + Draws the intersection points in a 3D view. + + Parameters + ---------- + view : View3d + The 3D view in which to draw the intersection points. + style : RenderControlPointSeq, optional + The style to use for rendering the points. Defaults to None. + """ + # "ChatGPT 4o" assisted with generating this docstring. if style is None: style = RenderControlPointSeq() self.intersection_points.draw_points(view, style) def draw_subset(self, view: View3d, count: int, points_style: RenderControlPointSeq = None): + """ + Draws a subset of intersection points in a 3D view. + + Parameters + ---------- + view : View3d + The 3D view in which to draw the intersection points. + count : int + The number of points to draw from the intersection points. + points_style : RenderControlPointSeq, optional + The style to use for rendering the points. Defaults to None. + """ + # "ChatGPT 4o" assisted with generating this docstring. for i in np.floor(np.linspace(0, len(self.intersection_points) - 1, count)): p = Pxyz(self.intersection_points[int(i)]) p.draw_points(view) diff --git a/opencsp/common/lib/geometry/TranslationXYZ.py b/opencsp/common/lib/geometry/TranslationXYZ.py index 36846452d..d96c124fa 100644 --- a/opencsp/common/lib/geometry/TranslationXYZ.py +++ b/opencsp/common/lib/geometry/TranslationXYZ.py @@ -5,9 +5,45 @@ class TranslationXYZ: + """ + DEPRECATED: A class representing a translation in 3D space. + + This class is deprecated and should be replaced with the Vxyz class for handling translations. + + Attributes + ---------- + trans_mtrx : np.ndarray + A 3x1 matrix representing the translation vector in 3D space. + """ + + # "ChatGPT 4o" assisted with generating this docstring. def __init__(self) -> None: + """ + DEPRECATED: Initializes the TranslationXYZ instance. + + This constructor creates a zero translation matrix and issues a deprecation warning. + + Raises + ------ + DeprecationWarning + Indicates that TranslationXYZ is deprecated and should be replaced with Vxyz. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn('TranslationXYZ is deprecated. Replace with Vxyz.', DeprecationWarning, stacklevel=2) self.trans_mtrx = np.zeros((3, 1)) def from_vector(v: Vxyz): + """ + DEPRECATED: Initializes the translation matrix from a Vxyz vector. + + Parameters + ---------- + v : Vxyz + A Vxyz object representing the translation vector. + + Returns + ------- + None + """ + # "ChatGPT 4o" assisted with generating this docstring. pass diff --git a/opencsp/common/lib/geometry/Uxy.py b/opencsp/common/lib/geometry/Uxy.py index 2d69baa8f..666616d64 100644 --- a/opencsp/common/lib/geometry/Uxy.py +++ b/opencsp/common/lib/geometry/Uxy.py @@ -2,7 +2,31 @@ class Uxy(Vxy): + """ + A class representing a 2D unit vector. + + This class extends the Vxy class to ensure that the vector is normalized upon initialization, + representing a direction in 2D space with a magnitude of 1. + """ + + # "ChatGPT 4o" assisted with generating this docstring. def __init__(self, data, dtype=float): + """ + Initializes the Uxy instance and normalizes the vector. + + Parameters + ---------- + data : array-like + The initial data for the vector, which should be a 2D vector. + dtype : type, optional + The data type of the vector elements. Defaults to float. + + Raises + ------ + ValueError + If the provided data does not represent a valid 2D vector. + """ + # "ChatGPT 4o" assisted with generating this docstring. # Initialize vector super().__init__(data, dtype) @@ -10,7 +34,16 @@ def __init__(self, data, dtype=float): self.normalize_in_place() def __repr__(self): - return '3D Unit Vector:\n' + self._data.__repr__() + return '2D Unit Vector:\n' + self._data.__repr__() def as_Vxy(self): + """ + Converts the Uxy instance to a Vxy instance. + + Returns + ------- + Vxy + A Vxy instance representing the same vector data. + """ + # "ChatGPT 4o" assisted with generating this docstring. return Vxy(self._data, self.dtype) diff --git a/opencsp/common/lib/geometry/angle.py b/opencsp/common/lib/geometry/angle.py index 0433f72e4..b77599e38 100644 --- a/opencsp/common/lib/geometry/angle.py +++ b/opencsp/common/lib/geometry/angle.py @@ -1,8 +1,5 @@ """ Angle Management - - - """ import math @@ -18,12 +15,45 @@ def coord2deg_aux(xy_or_xyz, idx): + """ + Converts the specified coordinate (x, y, or z) from radians to degrees. + + Parameters + ---------- + xy_or_xyz : np.ndarray + A 1D array representing a point in 2D or 3D space. + idx : int + The index of the coordinate to convert (0 for x, 1 for y, 2 for z). + + Returns + ------- + np.ndarray + A copy of the input array with the specified coordinate converted to degrees. + """ + # "ChatGPT 4o" assisted with generating this docstring. pt = xy_or_xyz.copy() pt[idx] = np.rad2deg(pt[idx]) return pt def coord2deg(xy_or_xyz_or_xy_seq_or_xyz_seq, idx): + """ + Converts the specified coordinate from radians to degrees for a single point or a sequence of points. + + Parameters + ---------- + xy_or_xyz_or_xy_seq_or_xyz_seq : np.ndarray or Iterable[np.ndarray] + A single point (2D or 3D) or a sequence of points to convert. + idx : int + The index of the coordinate to convert (0 for x, 1 for y, 2 for z). + + Returns + ------- + list[np.ndarray] + A list of points with the specified coordinate converted to degrees. + Returns an empty list if the input is empty. + """ + # "ChatGPT 4o" assisted with generating this docstring. if len(xy_or_xyz_or_xy_seq_or_xyz_seq) == 0: # Then the input xy_or_xyz_or_xy_seq_or_xyz_seq can be interpreted # as an input sequence, that has zero length. @@ -41,40 +71,127 @@ def coord2deg(xy_or_xyz_or_xy_seq_or_xyz_seq, idx): def x2deg(xy_or_xyz_or_xy_seq_or_xyz_seq): + """ + Converts the x-coordinates of a point or sequence of points from radians to degrees. + + Parameters + ---------- + xy_or_xyz_or_xy_seq_or_xyz_seq : np.ndarray or Iterable[np.ndarray] + A single point (2D or 3D) or a sequence of points. + + Returns + ------- + list[np.ndarray] + A list of points with the x-coordinates converted to degrees. + """ + # "ChatGPT 4o" assisted with generating this docstring. return coord2deg(xy_or_xyz_or_xy_seq_or_xyz_seq, 0) def y2deg(xy_or_xyz_or_xy_seq_or_xyz_seq): + """ + Converts the y-coordinates of a point or sequence of points from radians to degrees. + + Parameters + ---------- + xy_or_xyz_or_xy_seq_or_xyz_seq : np.ndarray or Iterable[np.ndarray] + A single point (2D or 3D) or a sequence of points. + + Returns + ------- + list[np.ndarray] + A list of points with the y-coordinates converted to degrees. + """ + # "ChatGPT 4o" assisted with generating this docstring. return coord2deg(xy_or_xyz_or_xy_seq_or_xyz_seq, 1) def z2deg(xyz_or_xyz_seq): + """ + Converts the z-coordinates of a point or sequence of points from radians to degrees. + + Parameters + ---------- + xyz_or_xyz_seq : np.ndarray or Iterable[np.ndarray] + A single point (3D) or a sequence of points. + + Returns + ------- + list[np.ndarray] + A list of points with the z-coordinates converted to degrees. + """ + # "ChatGPT 4o" assisted with generating this docstring. return coord2deg(xyz_or_xyz_seq, 2) def p2deg(pq_or_pq_seq): + """ + Converts the p-coordinates of a point or sequence of points from radians to degrees. + + Parameters + ---------- + pq_or_pq_seq : np.ndarray or Iterable[np.ndarray] + A single point (2D) or a sequence of points. + + Returns + ------- + list[np.ndarray] + A list of points with the p-coordinates converted to degrees. + """ + # "ChatGPT 4o" assisted with generating this docstring. return coord2deg(pq_or_pq_seq, 0) def q2deg(pq_or_pq_seq): + """ + Converts the q-coordinates of a point or sequence of points from radians to degrees. + + Parameters + ---------- + pq_or_pq_seq : np.ndarray or Iterable[np.ndarray] + A single point (2D) or a sequence of points. + + Returns + ------- + list[np.ndarray] + A list of points with the q-coordinates converted to degrees. + """ + # "ChatGPT 4o" assisted with generating this docstring. return coord2deg(pq_or_pq_seq, 1) @overload def normalize(angle: float) -> float: + """Normalizes a single angle to the range [0, 2π].""" + # "ChatGPT 4o" assisted with generating this docstring. pass @overload def normalize(angles: npt.NDArray[np.float_] | Iterable) -> npt.NDArray[np.float_]: + """Normalizes an array of angles to the range [0, 2π].""" + # "ChatGPT 4o" assisted with generating this docstring. pass def normalize(angle_or_angles: float | npt.NDArray[np.float_] | Iterable) -> float | npt.NDArray[np.float_]: - """Adjusts the given angle_or_angles to be in the range 0-2π. + """ + Adjusts the given angle or angles to be in the range [0, 2π]. + Note that because this function operates on floating point math, - your answer is not guaranteed to be exact (for example, a value - of -1e-16 could return 2π).""" + the result may not be exact (e.g., a value of -1e-16 could return 2π). + + Parameters + ---------- + angle_or_angles : float or npt.NDArray[np.float_] or Iterable + A single angle or an array/iterable of angles to normalize. + + Returns + ------- + float or npt.NDArray[np.float_] + The normalized angle or array of normalized angles. + """ + # "ChatGPT 4o" assisted with generating this docstring. if isinstance(angle_or_angles, np.ndarray): angles: np.ndarray = angle_or_angles # limit to the range +-pi @@ -96,14 +213,28 @@ def normalize(angle_or_angles: float | npt.NDArray[np.float_] | Iterable) -> flo def angle2_minus_angle_1(angle_1, angle_2): """ - Returns the signed small angle between the two input angles. - In most cases, this will simply be (angle_2 - angle_1). - However, we correct for cases where the angles wrap around 2pi. - Examples: - angle 1 = 5deg, angle_2 = 10 deg ==> 5 deg. - angle 1 = 355deg, angle_2 = 10 deg ==> 15 deg. - angle 1 = -5deg, angle_2 = -10 deg ==> -5 deg. - angle 1 = 5deg, angle_2 = -10 deg ==> -15 deg. + Calculates the signed small angle between two input angles. + + This function corrects for cases where the angles wrap around 2π. + + Parameters + ---------- + angle_1 : float + The first angle in radians. + angle_2 : float + The second angle in radians. + + Returns + ------- + float + The signed angle difference between angle_2 and angle_1, adjusted for wrapping. + + Examples + -------- + - angle_1 = 5 degrees, angle_2 = 10 degrees ==> 5 degrees + - angle_1 = 355 degrees, angle_2 = 10 degrees ==> 15 degrees + - angle_1 = -5 degrees, angle_2 = -10 degrees ==> -5 degrees + - angle_1 = 5 degrees, angle_2 = -10 degrees ==> -15 degrees """ two_pi = 2 * math.pi diff = angle_2 - angle_1 diff --git a/opencsp/common/lib/geometry/geometry_2d.py b/opencsp/common/lib/geometry/geometry_2d.py index 6d4ed568b..bd25a3899 100644 --- a/opencsp/common/lib/geometry/geometry_2d.py +++ b/opencsp/common/lib/geometry/geometry_2d.py @@ -1,8 +1,5 @@ """ 2-d Geometry Utiltiies - - - """ import math @@ -18,6 +15,32 @@ def homogeneous_line(xy1, xy2): + """ + DEPRECATED: Calculates the homogeneous line coefficients from two points. + + This function returns the coefficients of the line in homogeneous coordinates, + normalized to ensure the coefficients are in a standard form. + + Parameters + ---------- + xy1 : np.ndarray + The coordinates of the first point (x1, y1). + xy2 : np.ndarray + The coordinates of the second point (x2, y2). + + Returns + ------- + list[float] + A list containing the normalized coefficients [A, B, C] of the line equation Ax + By + C = 0. + + Raises + ------ + AssertionError + If the two points are the same, resulting in a degenerate case. + DeprecationWarning + geometry_2d.homogeneous_line is deprecated. Use LineXY instead. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn('geometry_2d.homogeneous_line is deprecated. Use LineXY instead.', DeprecationWarning, stacklevel=2) # Returns homogeneous line coeffcients, in normalized form. x1 = xy1[0] @@ -41,6 +64,25 @@ def homogeneous_line(xy1, xy2): def flip_homogeneous_line(line): + """ + DEPRECATED: Reverses the sense of the homogeneous line. + + Parameters + ---------- + line : list[float] + The coefficients of the line in homogeneous coordinates [A, B, C]. + + Returns + ------- + list[float] + The coefficients of the flipped line. + + Raises + ------ + DeprecationWarning + geometry_2d.flip_homogeneous_line is deprecated. Use LineXY.flip() instead. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_2d.flip_homogeneous_line is deprecated. Use LineXY.flip() instead.', DeprecationWarning, stacklevel=2 ) @@ -49,6 +91,27 @@ def flip_homogeneous_line(line): def homogeneous_line_signed_distance_to_xy(xy, line): + """ + DEPRECATED: Calculates the signed distance from a point to a homogeneous line. + + Parameters + ---------- + xy : np.ndarray + The coordinates of the point (x, y). + line : list[float] + The coefficients of the line in homogeneous coordinates [A, B, C]. + + Returns + ------- + float + The signed distance from the point to the line. + + Raises + ------ + DeprecationWarning + geometry_2d.homogeneous_line_signed_distance_to_xy is deprecated. Use LineXY.dist_from_line_signed() instead. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_2d.homogeneous_line_signed_distance_to_xy is deprecated. Use LineXY.dist_from_line_signed() instead.', DeprecationWarning, @@ -63,6 +126,28 @@ def homogeneous_line_signed_distance_to_xy(xy, line): def homogeneous_line_y_given_x(x, line): + """ + DEPRECATED: Calculates the y-coordinate on a homogeneous line given an x-coordinate. + + Parameters + ---------- + x : float + The x-coordinate for which to find the corresponding y-coordinate on the line. + line : list[float] + The coefficients of the line in homogeneous coordinates [A, B, C]. + + Returns + ------- + float + The y-coordinate corresponding to the given x-coordinate on the line. + Returns NaN if the line is vertical (B = 0). + + Raises + ------ + DeprecationWarning + geometry_2d.homogeneous_line_y_given_x is deprecated. Use LineXY.y_from_x() instead. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_2d.homogeneous_line_y_given_x is deprecated. Use LineXY.y_from_x() instead.', DeprecationWarning, @@ -78,6 +163,28 @@ def homogeneous_line_y_given_x(x, line): def homogeneous_line_x_given_y(y, line): + """ + DEPRECATED: Calculates the x-coordinate on a homogeneous line given a y-coordinate. + + Parameters + ---------- + y : float + The y-coordinate for which to find the corresponding x-coordinate on the line. + line : list[float] + The coefficients of the line in homogeneous coordinates [A, B, C]. + + Returns + ------- + float + The x-coordinate corresponding to the given y-coordinate on the line. + Returns NaN if the line is horizontal (A = 0). + + Raises + ------ + DeprecationWarning + geometry_2d.homogeneous_line_x_given_y is deprecated. Use LineXY.x_from_y() instead. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_2d.homogeneous_line_x_given_y is deprecated. Use LineXY.x_from_y() instead.', DeprecationWarning, @@ -93,6 +200,29 @@ def homogeneous_line_x_given_y(y, line): def intersect_lines(line1, line2): + """ + DEPRECATED: Calculates the intersection point of two homogeneous lines. + + Parameters + ---------- + line1 : list[float] + The coefficients of the first line in homogeneous coordinates [A1, B1, C1]. + line2 : list[float] + The coefficients of the second line in homogeneous coordinates [A2, B2, C2]. + + Returns + ------- + list[float] + The intersection point (x, y) of the two lines. Returns [NaN, NaN] if the lines are parallel. + + Raises + ------ + ValueError + If the lines are parallel and do not intersect. + DeprecationWarning + geometry_2d.intersect_lines is deprecated. Use LineXY.intersect_with() instead. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_2d.intersect_lines is deprecated. Use LineXY.intersect_with() instead.', DeprecationWarning, @@ -122,6 +252,27 @@ def intersect_lines(line1, line2): def shift_x(ray, dx): + """ + DEPRECATED: Shifts a ray in the x-direction by a specified amount. + + Parameters + ---------- + ray : list[list[float]] + A list containing two points that define the ray, each represented as [x, y]. + dx : float + The amount to shift the ray in the x-direction. + + Returns + ------- + list[list[float]] + A new ray represented by two points shifted in the x-direction. + + Raises + ------ + DeprecationWarning + geometry_2d.shift_x is deprecated. Use Vxy.__add__() instead. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn('geometry_2d.shift_x is deprecated. Use Vxy.__add__() instead.', DeprecationWarning, stacklevel=2) x0 = ray[0][0] y0 = ray[0][1] @@ -131,6 +282,27 @@ def shift_x(ray, dx): def intersect_rays(ray1, ray2): + """ + DEPRECATED: Calculates the intersection point of two rays. + + Parameters + ---------- + ray1 : list[list[float]] + A list containing two points that define the first ray, each represented as [x, y]. + ray2 : list[list[float]] + A list containing two points that define the second ray, each represented as [x, y]. + + Returns + ------- + list[float] + The intersection point (x, y) of the two rays. Returns [NaN, NaN] if the rays do not intersect. + + Raises + ------ + DeprecationWarning + geometry_2d.intersect_rays is deprecated. Use LineXY.intersect_with() instead. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_2d.intersect_rays is deprecated. Use LineXY.intersect_with() instead.', DeprecationWarning, @@ -147,6 +319,22 @@ def intersect_rays(ray1, ray2): def draw_clip_xy_box(view, clip_xy_box): + """ + DEPRECATED: Draws a clipping box in the XY plane. + + Parameters + ---------- + view : object + The view object in which to draw the clipping box. + clip_xy_box : tuple[tuple[float, float], tuple[float, float]] + A tuple defining the clipping box as ((xmin, xmax), (ymin, ymax)). + + Raises + ------ + DeprecationWarning + geometry_2d.draw_clip_xy_box is deprecated. Should be migrated to another library. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_2d.draw_clip_xy_box is deprecated. Should be migrated to another library.', DeprecationWarning, @@ -163,6 +351,27 @@ def draw_clip_xy_box(view, clip_xy_box): def clip_line_to_xy_box(line, clip_xy_box): + """ + DEPRECATED: Clips a line to the specified XY clipping box. + + Parameters + ---------- + line : list[float] + The coefficients of the line in homogeneous coordinates [A, B, C]. + clip_xy_box : tuple[tuple[float, float], tuple[float, float]] + A tuple defining the clipping box as ((xmin, xmax), (ymin, ymax)). + + Returns + ------- + list[list[float]] + A list of points where the line intersects the clipping box edges. + Returns an empty list if the line is completely outside the clipping box. + + Raises + ------ + geometry_2d.clip_line_to_xy_box is deprecated. Should be migrated to another library. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_2d.clip_line_to_xy_box is deprecated. Should be migrated to another library.', DeprecationWarning, @@ -207,6 +416,32 @@ def clip_line_to_xy_box(line, clip_xy_box): def extend_ray(ray, clip_xy_box, fail_if_null_result=True): + """ + DEPRECATED: Extends a ray to intersect with the specified clipping box. + + Parameters + ---------- + ray : list[list[float]] + A list containing two points that define the ray, each represented as [x, y]. + clip_xy_box : tuple[tuple[float, float], tuple[float, float]] + A tuple defining the clipping box as ((xmin, xmax), (ymin, ymax)). + fail_if_null_result : bool, optional + If True, raises an error if the ray does not intersect the clipping box. Defaults to True. + + Returns + ------- + list[list[float]] + A new ray represented by two points that extend to the clipping box. + Returns None if the ray is completely outside the clipping box and fail_if_null_result is False. + + Raises + ------ + AssertionError + If the ray is completely outside the clipping box and fail_if_null_result is True. + DeprecationWarning + geometry_2d.extend_ray is deprecated. Should be migrated to another library. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_2d.extend_ray is deprecated. Should be migrated to another library.', DeprecationWarning, stacklevel=2 ) @@ -280,6 +515,30 @@ def extend_ray(ray, clip_xy_box, fail_if_null_result=True): # this allows code to work if data are a vertical or horizontal line. # def best_fit_line_segment_A(xy_seq): + """ + DEPRECATED: Calculates the best-fit line segment for a sequence of 2D points. + + This function determines the best-fit line segment that minimizes the distance + to a set of points in 2D space. + + Parameters + ---------- + xy_seq : list[list[float]] + A list of points where each point is represented as [x, y]. + + Returns + ------- + list[list[float]] + A list containing two points that define the best-fit line segment. + + Raises + ------ + AssertionError + If the input points are ill-conditioned (all points are the same). + DeprecationWarning + geometry_2d.best_fit_line_segment_A is deprecated. Use LineXY.fit_from_points() instead. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_2d.best_fit_line_segment_A is deprecated. Use LineXY.fit_from_points() instead.', DeprecationWarning, @@ -345,6 +604,28 @@ def best_fit_line_segment_A(xy_seq): def best_fit_line_segment(xy_list): + """ + DEPRECATED: Calculates the best-fit line segment for a sequence of 2D points. + + This function determines the best-fit line segment that minimizes the distance + to a set of points in 2D space. This is a deprecated function; use LineXY.fit_from_points() instead. + + Parameters + ---------- + xy_list : list[list[float]] + A list of points where each point is represented as [x, y]. + + Returns + ------- + list[list[float]] + A list containing two points that define the best-fit line segment. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should be replaced with LineXY.fit_from_points(). + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_2d.best_fit_line_segment is deprecated. Use LineXY.fit_from_points() instead.', DeprecationWarning, @@ -359,6 +640,30 @@ def best_fit_line_segment(xy_list): def rotate_about_origin(xy, theta): + """ + DEPRECATED: Rotates a point around the origin by a specified angle. + + This function rotates the point (x, y) by the angle theta (in radians) around the origin (0, 0). + This is a deprecated function; use Vxy.rotate() or TransformXY instead. + + Parameters + ---------- + xy : list[float] + The coordinates of the point to rotate, represented as [x, y]. + theta : float + The angle of rotation in radians. + + Returns + ------- + list[float] + The new coordinates of the point after rotation, represented as [x', y']. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should be replaced with Vxy.rotate() or TransformXY. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_2d.rotate_about_origin is deprecated. Use Vxy.rotate() or TransformXY instead.', DeprecationWarning, @@ -374,6 +679,32 @@ def rotate_about_origin(xy, theta): def rotate_about_center(xy, theta, center_xy): + """ + DEPRECATED: Rotates a point around a specified center by a specified angle. + + This function rotates the point (x, y) around the point (cx, cy) by the angle theta (in radians). + This is a deprecated function; use TransformXY instead. + + Parameters + ---------- + xy : list[float] + The coordinates of the point to rotate, represented as [x, y]. + theta : float + The angle of rotation in radians. + center_xy : list[float] + The coordinates of the center point around which to rotate, represented as [cx, cy]. + + Returns + ------- + list[float] + The new coordinates of the point after rotation, represented as [x', y']. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should be replaced with TransformXY. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn('geometry_2d.rotate_about_center is deprecated. Use TransformXY instead.', DeprecationWarning, stacklevel=2) x = xy[0] y = xy[1] @@ -391,8 +722,31 @@ def rotate_about_center(xy, theta, center_xy): def rotate_xyz_about_center_xy(xyz, theta, center_xy): """ - A planar rotation. That is, the rotation axis is parallel to the z axis. + DEPRECATED: Rotates a 3D point around a specified center in the XY plane. + + This function performs a planar rotation of the point (x, y, z) around the center (cx, cy) + by the angle theta (in radians). The z-coordinate remains unchanged. + + Parameters + ---------- + xyz : list[float] + The coordinates of the point to rotate, represented as [x, y, z]. + theta : float + The angle of rotation in radians. + center_xy : list[float] + The coordinates of the center point around which to rotate, represented as [cx, cy]. + + Returns + ------- + list[float] + The new coordinates of the point after rotation, represented as [x', y', z]. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should be replaced with TransformXYZ, TransformXY, Vxyz.rotate(), or Vxy.rotate(). """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_2d.rotate_xyz_about_center_xy is deprecated. Use TransformXYZ, TransformXY, Vxyz.rotate() oro Vxy.rotate() instead.', DeprecationWarning, @@ -419,6 +773,28 @@ def rotate_xyz_about_center_xy(xyz, theta, center_xy): def label_point(xy_list): + """ + DEPRECATED: Calculates a central label point for a list of 2D points. + + This function computes a reasonable central label point for a given list of points. + It calculates the mean of the x and y coordinates of the points. + + Parameters + ---------- + xy_list : list[list[float]] + A list of points where each point is represented as [x, y]. + + Returns + ------- + list[float] + The coordinates of the central label point, represented as [x_mean, y_mean]. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should be migrated to another library. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_2d.label_point is deprecated. Should be migrated to another library.', DeprecationWarning, diff --git a/opencsp/common/lib/geometry/geometry_3d.py b/opencsp/common/lib/geometry/geometry_3d.py index 1023dfe62..7540fd0fa 100644 --- a/opencsp/common/lib/geometry/geometry_3d.py +++ b/opencsp/common/lib/geometry/geometry_3d.py @@ -12,6 +12,30 @@ def direction_uxyz_given_azimuth_elevation(azimuth: float, elevation: float): # Both radians. + """ + DEPRECATED: Calculates the direction vector in 3D space given azimuth and elevation angles. + + This function converts azimuth and elevation angles (in radians) into a unit vector + in 3D space. + + Parameters + ---------- + azimuth : float + The azimuth angle in radians, measured from the positive x-axis. + elevation : float + The elevation angle in radians, measured from the xy-plane. + + Returns + ------- + np.ndarray + A 3D unit vector representing the direction corresponding to the given azimuth and elevation. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should be migrated to another library. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_3d.direction_uxyz_given_azimuth_elevation is deprecated. This function should be migrated to another library.', DeprecationWarning, @@ -30,6 +54,27 @@ def direction_uxyz_given_azimuth_elevation(azimuth: float, elevation: float): # def distance_between_xyz_points(xyz_1, xyz_2): + """ + DEPRECATED: Calculates the Euclidean distance between two points in 3D space. + + Parameters + ---------- + xyz_1 : np.ndarray + The coordinates of the first point (x1, y1, z1). + xyz_2 : np.ndarray + The coordinates of the second point (x2, y2, z2). + + Returns + ------- + float + The Euclidean distance between the two points. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should use Vxyz subtraction/magnitude instead. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_3d.distance_between_xyz_points is deprecated. Use Vxyz subtraction/magnitude instead.', DeprecationWarning, @@ -50,6 +95,27 @@ def distance_between_xyz_points(xyz_1, xyz_2): def vector_3d_cross_product(vxyz_1, vxyz_2): + """ + DEPRECATED: Calculates the cross product of two 3D vectors. + + Parameters + ---------- + vxyz_1 : np.ndarray + The first vector represented as an array-like object [x1, y1, z1]. + vxyz_2 : np.ndarray + The second vector represented as an array-like object [x2, y2, z2]. + + Returns + ------- + list[float] + The resulting vector from the cross product, represented as [x, y, z]. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should use Vxyz.cross() instead. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_3d.vector_3d_cross_product is deprecated. Use Vxyz.cross() instead.', DeprecationWarning, stacklevel=2 ) @@ -59,11 +125,49 @@ def vector_3d_cross_product(vxyz_1, vxyz_2): def vector_3d_norm(vxyz): + """ + DEPRECATED: Calculates the norm (magnitude) of a 3D vector. + + Parameters + ---------- + vxyz : np.ndarray + The vector represented as an array-like object [x, y, z]. + + Returns + ------- + float + The magnitude of the vector. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should use Vxyz.magnitude() instead. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn('geometry_3d.vector_3d_norm is deprecated. Use Vxyz.magnitude() instead.', DeprecationWarning, stacklevel=2) return np.sqrt(vxyz[0] ** 2 + vxyz[1] ** 2 + vxyz[2] ** 2) def normalize_vector_3d(vxyz): + """ + DEPRECATED: Normalizes a 3D vector to unit length. + + Parameters + ---------- + vxyz : np.ndarray + The vector represented as an array-like object [x, y, z]. + + Returns + ------- + list[float] + The normalized vector represented as [x', y', z']. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should use Vxyz.normalize() instead. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_3d.normalize_vector_3d is deprecated. Use Vxyz.normalize() instead.', DeprecationWarning, stacklevel=2 ) @@ -114,6 +218,31 @@ def normalize_vector_3d(vxyz): # return a, b, c # def best_fit_plane_B(xs, ys, zs): + """ + DEPRECATED: Calculates the coefficients of the best-fit plane for a set of 3D points. + + This function computes the best-fit plane that minimizes the distance to a set of points in 3D space. + + Parameters + ---------- + xs : list[float] + A list of x-coordinates of the points. + ys : list[float] + A list of y-coordinates of the points. + zs : list[float] + A list of z-coordinates of the points. + + Returns + ------- + list[float] + A list containing the coefficients [A, B, C] of the plane equation Ax + By + Cz + D = 0. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should be migrated to another library. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_3d.best_fit_plane_B is deprecated. Should be migrated to another library.', DeprecationWarning, @@ -152,6 +281,28 @@ def best_fit_plane_B(xs, ys, zs): def best_fit_plane(xyz_list): + """ + DEPRECATED: Calculates the coefficients of the best-fit plane for a sequence of 3D points. + + This function converts the list of 3D points into separate coordinate lists and + computes the best-fit plane coefficients. + + Parameters + ---------- + xyz_list : list[list[float]] + A list of points where each point is represented as [x, y, z]. + + Returns + ------- + list[float] + A list containing the coefficients [A, B, C] of the plane equation Ax + By + Cz + D = 0. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should be migrated to another library. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_3d.best_fit_plane is deprecated. Should be migrated to another library.', DeprecationWarning, @@ -171,6 +322,25 @@ def best_fit_plane(xyz_list): def flip_homogeneous_plane(plane): + """ + Reverses the sense of the homogeneous plane. + + Parameters + ---------- + plane : list[float] + The coefficients of the plane in homogeneous coordinates [A, B, C, D]. + + Returns + ------- + list[float] + The coefficients of the flipped plane. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should be migrated to another library. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_3d.flip_homogeneous_plane is deprecated. Should be migrated to another library.', DeprecationWarning, @@ -181,6 +351,27 @@ def flip_homogeneous_plane(plane): def homogeneous_plane_signed_distance_to_xyz(xyz, plane): + """ + DEPRECATED: Calculates the signed distance from a point to a homogeneous plane. + + Parameters + ---------- + xyz : list[float] + The coordinates of the point (x, y, z). + plane : list[float] + The coefficients of the plane in homogeneous coordinates [A, B, C, D]. + + Returns + ------- + float + The signed distance from the point to the plane. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should be migrated to another library. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_3d.homogeneous_plane_signed_distance_to_xyz is deprecated. Should be migrated to another library.', DeprecationWarning, @@ -205,9 +396,33 @@ def construct_line_3d_given_two_points( xyz_1, xyz_2, tolerance=0.0 ): # ?? SCAFFOLDING RCB -- THE 3-D LINE SHOULD BE A CLASS. """ - A line_3d is an infinite line. - It is not bounded by its defining points; that would be a line segment. + DEPRECATED: Constructs a 3D line from two points. + + This function creates a representation of an infinite line defined by two points in 3D space. + + Parameters + ---------- + xyz_1 : list[float] + The coordinates of the first point (x1, y1, z1). + xyz_2 : list[float] + The coordinates of the second point (x2, y2, z2). + tolerance : float, optional + A tolerance value to determine if the two points are considered the same. Defaults to 0.0. + + Returns + ------- + dict + A dictionary containing attributes of the line, including its length, midpoint, and direction. + + Raises + ------ + AssertionError + If the two points are the same or too close to each other. + + DeprecationWarning + Indicates that this function is deprecated and should be migrated to another library. """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_3d.construct_line_3d_given_two_points is deprecated. Should be migrated to another library.', DeprecationWarning, @@ -254,8 +469,28 @@ def construct_line_3d_given_two_points( def closest_point_on_line_3d(xyz, line_3d): # ?? SCAFFOLDING RCB -- THE 3-D LINE SHOULD BE A CLASS. """ - Returns the point on the infinite 3d line that is closest to the given point. + DEPRECATED: Finds the closest point on a 3D line to a given point. + + This function calculates the point on the infinite line that is closest to the specified point in 3D space. + + Parameters + ---------- + xyz : list[float] + The coordinates of the point (x, y, z). + line_3d : dict + A dictionary representing the line, containing attributes such as 'mid_xyz' and 'uxyz'. + + Returns + ------- + list[float] + The coordinates of the closest point on the line to the given point. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should be migrated to another library. """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_3d.closest_point_on_line_3d is deprecated. Should be migrated to another library.', DeprecationWarning, @@ -291,8 +526,26 @@ def closest_point_on_line_3d(xyz, line_3d): # ?? SCAFFOLDING RCB -- THE 3-D LIN def distance_to_line_3d(xyz, line_3d): # ?? SCAFFOLDING RCB -- THE 3-D LINE SHOULD BE A CLASS. """ - Returns the shortest distance from the given point to the infinite 3-d line. + DEPRECATED: Calculates the shortest distance from a point to an infinite 3D line. + + Parameters + ---------- + xyz : list[float] + The coordinates of the point (x, y, z). + line_3d : dict + A dictionary representing the line, containing attributes such as 'mid_xyz' and 'uxyz'. + + Returns + ------- + float + The shortest distance from the point to the line. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should be migrated to another library. """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'geometry_3d.distance_to_line_3d is deprecated. Should be migrated to another library.', DeprecationWarning, diff --git a/opencsp/common/lib/geometry/transform_3d.py b/opencsp/common/lib/geometry/transform_3d.py index 245a06756..2d5f56379 100644 --- a/opencsp/common/lib/geometry/transform_3d.py +++ b/opencsp/common/lib/geometry/transform_3d.py @@ -1,8 +1,5 @@ """ -Trransforms, Included Rotation and Translation - - - +Transforms, Included Rotation and Translation """ import math @@ -11,6 +8,32 @@ def axisrotation(unit_vector, angle): # ?? SCAFFOLDING RCB -- ADD UNDERSCORE BETWEEN "AXIS" AND "ROTATION" + """ + DEPRECATED: Calculates the rotation matrix for a given angle around a specified axis. + + This function uses the right-hand rule to compute the rotation matrix based on + the provided unit vector and angle. The angle is expected to be in radians. + + Parameters + ---------- + unit_vector : np.ndarray + A 3D unit vector representing the axis of rotation. + angle : float + The angle of rotation in radians. + + Returns + ------- + np.ndarray + A 3x3 rotation matrix corresponding to the rotation around the specified axis. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should be replaced with scipy.spatial.transform.Rotation. + AssertionError + If the input unit_vector is not of unit length. + """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'transform_3d.axisrotation is deprecated. Replace with scipy.spatial.transform.Rotation', DeprecationWarning, @@ -47,13 +70,33 @@ def axisrotation(unit_vector, angle): # ?? SCAFFOLDING RCB -- ADD UNDERSCORE BE def rotation_matrix_to_euler_angles(R): """ - Calculates rotation matrix to Euler angles. - The result is the same as MATLAB except the order - of the Euler angles (x and z are swapped). - + DEPRECATED: Converts a rotation matrix to Euler angles. + + This function computes the Euler angles corresponding to the given rotation matrix. + The order of the angles is such that the x and z angles are swapped compared to MATLAB. + + Parameters + ---------- + R : np.ndarray + A 3x3 rotation matrix. + + Returns + ------- + tuple[float, float, float] + A tuple containing the Euler angles (rot_x, rot_y, rot_z) in radians. + + Raises + ------ + AssertionError + If the input matrix is not a valid rotation matrix. + DeprecationWarning + Indicates that this function is deprecated and should be replaced with scipy.spatial.transform.Rotation. + + Notes + ----- See https://learnopencv.com/rotation-matrix-to-euler-angles/ - """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'transform_3d.rotation_matrix_to_euler_angles is deprecated. Replace with scipy.spatial.transform.Rotation.', DeprecationWarning, @@ -77,11 +120,30 @@ def rotation_matrix_to_euler_angles(R): def is_rotation_matrix(R): """ - Checks if a matrix is a valid rotation matrix. + DEPRECATED: Checks if a matrix is a valid rotation matrix. - See https://learnopencv.com/rotation-matrix-to-euler-angles/ + A valid rotation matrix must be orthogonal and have a determinant of 1. + + Parameters + ---------- + R : np.ndarray + A 3x3 matrix to check. + Returns + ------- + bool + True if the matrix is a valid rotation matrix, False otherwise. + + Raises + ------ + DeprecationWarning + Indicates that this function is deprecated and should be replaced with scipy.spatial.transform.Rotation. + + Notes + ----- + See https://learnopencv.com/rotation-matrix-to-euler-angles/ """ + # "ChatGPT 4o" assisted with generating this docstring. warn( 'transform_3d.is_rotation_matrix is deprecated. Replace with scipy.spatial.transform.Rotation.', DeprecationWarning, diff --git a/opencsp/common/lib/render_control/RenderControlIntersection.py b/opencsp/common/lib/render_control/RenderControlIntersection.py index 3f68d566e..96cda397b 100644 --- a/opencsp/common/lib/render_control/RenderControlIntersection.py +++ b/opencsp/common/lib/render_control/RenderControlIntersection.py @@ -4,9 +4,36 @@ class RenderControlIntersection: + """ + A class for controlling the rendering of intersection points in a graphical representation. + + This class allows for the configuration of the style of dots used to represent intersection points + and the limits of the plot area. + + Attributes + ---------- + dots_style : rcps.RenderControlPointSeq + The style of the dots used for rendering intersection points. + plot_limits : tuple[tuple, tuple] or None + The limits of the plot area, or None if not set. + """ + + # "ChatGPT 4o" assisted with generating this docstring. def __init__( self, dots_style=rcps.marker(), plot_limits: tuple[tuple, tuple] = None # ((xmin, xmax), (ymin, ymax)) ) -> None: + """ + Initializes the RenderControlIntersection instance with specified dot style and plot limits. + + Parameters + ---------- + dots_style : rcps.RenderControlPointSeq, optional + The style of the dots used for rendering intersection points. Defaults to a marker style. + plot_limits : tuple[tuple, tuple], optional + A tuple defining the limits of the plot area as ((xmin, xmax), (ymin, ymax)). + If None, the plot limits are not set. + """ + # "ChatGPT 4o" assisted with generating this docstring. self.dots_style: rcps.RenderControlPointSeq = dots_style self.plot_limits = plot_limits diff --git a/opencsp/test/test_DocStringsExist.py b/opencsp/test/test_DocStringsExist.py index cbadf3e3f..58491f548 100644 --- a/opencsp/test/test_DocStringsExist.py +++ b/opencsp/test/test_DocStringsExist.py @@ -22,6 +22,9 @@ import opencsp.common.lib.deflectometry.ParamsSlopeSolverAbstract as ParamsSlopeSolverAbstract import opencsp.common.lib.deflectometry.ParamsSlopeSolverParaboloid as ParamsSlopeSolverParaboloid import opencsp.common.lib.deflectometry.ParamsSlopeSolverPlano as ParamsSlopeSolverPlano +import opencsp.common.lib.geometry.ReferenceFrame as ReferenceFrame +import opencsp.common.lib.geometry.TranslationXYZ as TranslationXYZ +import opencsp.common.lib.geometry.matrix_geometry_3d as matrix_geometry_3d def test_docstrings_exist_for_methods(): @@ -179,8 +182,40 @@ def test_docstrings_exist_for_methods(): geo_class_list = [opencsp.common.lib.geo.lon_lat_nsttf] + geometry_class_list = [ + opencsp.common.lib.geometry.EdgeXY, + opencsp.common.lib.geometry.FunctionXYAbstract, + opencsp.common.lib.geometry.FunctionXYContinuous, + opencsp.common.lib.geometry.FunctionXYDiscrete, + opencsp.common.lib.geometry.FunctionXYGrid, + opencsp.common.lib.geometry.Intersection, + opencsp.common.lib.geometry.LineXY, + opencsp.common.lib.geometry.LoopXY, + opencsp.common.lib.geometry.Pxy, + opencsp.common.lib.geometry.Pxyz, + opencsp.common.lib.geometry.ReferenceFrame, + opencsp.common.lib.geometry.RegionXY, + opencsp.common.lib.geometry.TransformXYZ, + opencsp.common.lib.geometry.TranslationXYZ, + opencsp.common.lib.geometry.Uxy, + opencsp.common.lib.geometry.Uxyz, + opencsp.common.lib.geometry.Vxy, + opencsp.common.lib.geometry.Vxyz, + opencsp.common.lib.geometry.angle, + opencsp.common.lib.geometry.geometry_2d, + opencsp.common.lib.geometry.geometry_3d, + opencsp.common.lib.geometry.matrix_geometry_3d, + opencsp.common.lib.geometry.transform_3d, + ] + common_class_list = ( - camera_class_list + csp_class_list + cv_class_list + deflectometry_class_list + file_class_list + geo_class_list + camera_class_list + + csp_class_list + + cv_class_list + + deflectometry_class_list + + file_class_list + + geo_class_list + + geometry_class_list ) class_list = app_class_list + common_class_list