img_phy_sim.math
Mathematical and Geometric Utility Functions
This module provides lightweight mathematical helper functions for 2D geometry and angle-based computations. It is designed to support higher-level operations such as beam tracing, image-based simulations, and coordinate normalization.
The functions focus on conversions between angular and Cartesian representations, as well as normalization and denormalization of image coordinates.
Main features:
- Generate evenly spaced degree ranges for directional sampling
- Convert between degrees and 2D unit vectors
- Convert 2D vectors back to degree angles
- Normalize and denormalize 2D points for image-based coordinate systems
Typical use cases:
- Generating input directions for beam tracing or ray simulation
- Converting between angular and vector representations in geometric algorithms
- Preparing coordinates for normalized image processing workflows
Dependencies:
- math
- numpy
Example:
import img_phy_sim as ips
# Generate sample directions
directions = ips.math.get_linear_degree_range(step_size=45)
# Convert each to a 2D vector
vectors = [ips.math.degree_to_vector(d) for d in directions]
# Convert back to degrees
recovered = [ips.math.vector_to_degree(v) for v in vectors]
# Normalize and denormalize a point
p_norm = ips.math.normalize_point((128, 64), width=256, height=128)
p_pixel = ips.math.denormalize_point(p_norm, width=256, height=128)
Functions:
- get_linear_degree_range(...) - Generate evenly spaced degrees within a range.
- degree_to_vector(...) - Convert a degree angle to a 2D unit vector.
- vector_to_degree(...) - Convert a 2D vector into its corresponding degree.
- normalize_point(...) - Normalize a 2D point to [0, 1] range.
- denormalize_point(...) - Denormalize a 2D point to pixel coordinates.
- numpy_info(...) - Get statistics about an numpy array.
1""" 2**Mathematical and Geometric Utility Functions** 3 4This module provides lightweight mathematical helper functions for 2D geometry 5and angle-based computations. It is designed to support higher-level operations 6such as beam tracing, image-based simulations, and coordinate normalization. 7 8The functions focus on conversions between angular and Cartesian representations, 9as well as normalization and denormalization of image coordinates. 10 11Main features: 12- Generate evenly spaced degree ranges for directional sampling 13- Convert between degrees and 2D unit vectors 14- Convert 2D vectors back to degree angles 15- Normalize and denormalize 2D points for image-based coordinate systems 16 17Typical use cases: 18- Generating input directions for beam tracing or ray simulation 19- Converting between angular and vector representations in geometric algorithms 20- Preparing coordinates for normalized image processing workflows 21 22Dependencies: 23- math 24- numpy 25 26Example: 27```python 28import img_phy_sim as ips 29 30# Generate sample directions 31directions = ips.math.get_linear_degree_range(step_size=45) 32 33# Convert each to a 2D vector 34vectors = [ips.math.degree_to_vector(d) for d in directions] 35 36# Convert back to degrees 37recovered = [ips.math.vector_to_degree(v) for v in vectors] 38 39# Normalize and denormalize a point 40p_norm = ips.math.normalize_point((128, 64), width=256, height=128) 41p_pixel = ips.math.denormalize_point(p_norm, width=256, height=128) 42``` 43 44Functions: 45- get_linear_degree_range(...) - Generate evenly spaced degrees within a range. 46- degree_to_vector(...) - Convert a degree angle to a 2D unit vector. 47- vector_to_degree(...) - Convert a 2D vector into its corresponding degree. 48- normalize_point(...) - Normalize a 2D point to [0, 1] range. 49- denormalize_point(...) - Denormalize a 2D point to pixel coordinates. 50- numpy_info(...) - Get statistics about an numpy array. 51""" 52 53 54 55# --------------- 56# >>> Imports <<< 57# --------------- 58import math 59import numpy as np 60 61import numba 62 63 64 65# ----------------- 66# >>> Constants <<< 67# ----------------- 68_DEG2RAD = math.pi / 180.0 69_RAD2DEG = 180.0 / math.pi 70 71 72 73# ----------------- 74# >>> Functions <<< 75# ----------------- 76def get_linear_degree_range(start=0, stop=360, step_size=10, offset=0): 77 """ 78 Generate a list of degrees within a linear range. 79 80 Parameters: 81 - start (int, optional): Starting degree (default is 0). 82 - stop (int, optional): Ending degree (default is 360). 83 - step_size (int, optional): Step size between degrees (default is 10). 84 - offset (int, optional): Offset to add to each degree value (default is 0). 85 86 Returns: 87 - list: List of degree values adjusted by offset and modulo 360. 88 """ 89 degree_range = np.arange(start=start, stop=stop, step=step_size).tolist() # list(range(0, 360, step_size)) 90 return list(map(lambda x: (x+offset) % 360, degree_range)) 91 92 93 94def degree_to_vector(degree): 95 """ 96 Convert a degree angle to a 2D unit vector. 97 98 Parameters: 99 - degree (float): Angle in degrees. 100 101 Returns: 102 - list: 2D vector [cos(degree), sin(degree)]. 103 """ 104 # rad = math.radians(degree) 105 # return [math.cos(rad), math.sin(rad)] 106 rad = degree * _DEG2RAD 107 return (math.cos(rad), math.sin(rad)) 108 109 110 111 112def vector_to_degree(x, y): 113 """ 114 Convert a 2D vector into its corresponding degree angle. 115 116 Parameters: 117 - vector (tuple): 2D vector (x, y). 118 119 Returns: 120 - int: Angle in degrees within the range [0, 360). 121 """ 122 # x, y = vector 123 # degree = math.degrees(math.atan2(y, x)) # atan2 returns angles between -180° and 180° 124 # return int( degree % 360 ) 125 deg = math.atan2(y, x) * _RAD2DEG 126 return int(deg % 360.0) 127 128 129 130def normalize_point(x, y, width, height): 131 """ 132 Normalize a 2D point to the range [0, 1]. 133 134 Parameters: 135 - point (tuple): (x, y) coordinates of the point. 136 - width (int): Image or grid width. 137 - height (int): Image or grid height. 138 139 Returns: 140 - tuple: Normalized point (x / (width - 1), y / (height - 1)). 141 """ 142 # return (x / (width - 1), y / (height - 1)) 143 return ( (1.0 / (width - 1.0))*x, 144 (1.0 / (height - 1.0))*y) 145 146 147 148 149def denormalize_point(x, y, width, height): 150 """ 151 Denormalize a 2D point from normalized coordinates back to pixel coordinates. 152 153 Parameters: 154 - point (tuple): Normalized (x, y) coordinates. 155 - width (int): Image or grid width. 156 - height (int): Image or grid height. 157 158 Returns: 159 - tuple: Denormalized point (x * (width - 1), y * (height - 1)). 160 """ 161 return (x * (width - 1.0), y * (height - 1.0)) 162 163 164 165def numpy_info(numpy_array, should_print=True): 166 """ 167 Print and return basic statistical information about a NumPy array. 168 169 Computes common descriptive statistics such as mean, median, standard 170 deviation, variance, minimum, maximum, and array shape. This function is 171 primarily intended for quick debugging and inspection of intermediate 172 results in numerical or image-processing pipelines. 173 174 Parameters: 175 - numpy_array (np.ndarray): Input NumPy array to analyze. 176 - should_print (bool): If True, print the statistics to stdout. 177 178 Returns: 179 - str: A formatted string containing the computed statistics. 180 """ 181 result = "Array Statistics:" 182 result += f"\n - mean = {numpy_array.mean():.2f}" 183 result += f"\n - median = {np.median(numpy_array):.2f}" 184 # result += f"\n - percentile = {np.percentile(numpy_array, [25, 50, 75])}" 185 result += f"\n - std = {numpy_array.std():.2f}" 186 result += f"\n - var = {numpy_array.var():.2f}" 187 result += f"\n - min = {numpy_array.min():.2f}" 188 result += f"\n - max = {numpy_array.max():.2f}" 189 result += f"\n - shape = {numpy_array.shape}" 190 191 if should_print: 192 print(result) 193 return result 194 195 196 197# ----------------------- 198# >>> Numba Functions <<< 199# ----------------------- 200degree_to_vector_numba = numba.njit(cache=True, fastmath=True)(degree_to_vector) 201vector_to_degree_numba = numba.njit(cache=True, fastmath=True)(vector_to_degree) 202normalize_point_numba = numba.njit(cache=True, fastmath=True)(normalize_point) 203denormalize_point_numba = numba.njit(cache=True, fastmath=True)(denormalize_point)
77def get_linear_degree_range(start=0, stop=360, step_size=10, offset=0): 78 """ 79 Generate a list of degrees within a linear range. 80 81 Parameters: 82 - start (int, optional): Starting degree (default is 0). 83 - stop (int, optional): Ending degree (default is 360). 84 - step_size (int, optional): Step size between degrees (default is 10). 85 - offset (int, optional): Offset to add to each degree value (default is 0). 86 87 Returns: 88 - list: List of degree values adjusted by offset and modulo 360. 89 """ 90 degree_range = np.arange(start=start, stop=stop, step=step_size).tolist() # list(range(0, 360, step_size)) 91 return list(map(lambda x: (x+offset) % 360, degree_range))
Generate a list of degrees within a linear range.
Parameters:
- start (int, optional): Starting degree (default is 0).
- stop (int, optional): Ending degree (default is 360).
- step_size (int, optional): Step size between degrees (default is 10).
- offset (int, optional): Offset to add to each degree value (default is 0).
Returns:
- list: List of degree values adjusted by offset and modulo 360.
95def degree_to_vector(degree): 96 """ 97 Convert a degree angle to a 2D unit vector. 98 99 Parameters: 100 - degree (float): Angle in degrees. 101 102 Returns: 103 - list: 2D vector [cos(degree), sin(degree)]. 104 """ 105 # rad = math.radians(degree) 106 # return [math.cos(rad), math.sin(rad)] 107 rad = degree * _DEG2RAD 108 return (math.cos(rad), math.sin(rad))
Convert a degree angle to a 2D unit vector.
Parameters:
- degree (float): Angle in degrees.
Returns:
- list: 2D vector [cos(degree), sin(degree)].
113def vector_to_degree(x, y): 114 """ 115 Convert a 2D vector into its corresponding degree angle. 116 117 Parameters: 118 - vector (tuple): 2D vector (x, y). 119 120 Returns: 121 - int: Angle in degrees within the range [0, 360). 122 """ 123 # x, y = vector 124 # degree = math.degrees(math.atan2(y, x)) # atan2 returns angles between -180° and 180° 125 # return int( degree % 360 ) 126 deg = math.atan2(y, x) * _RAD2DEG 127 return int(deg % 360.0)
Convert a 2D vector into its corresponding degree angle.
Parameters:
- vector (tuple): 2D vector (x, y).
Returns:
- int: Angle in degrees within the range [0, 360).
131def normalize_point(x, y, width, height): 132 """ 133 Normalize a 2D point to the range [0, 1]. 134 135 Parameters: 136 - point (tuple): (x, y) coordinates of the point. 137 - width (int): Image or grid width. 138 - height (int): Image or grid height. 139 140 Returns: 141 - tuple: Normalized point (x / (width - 1), y / (height - 1)). 142 """ 143 # return (x / (width - 1), y / (height - 1)) 144 return ( (1.0 / (width - 1.0))*x, 145 (1.0 / (height - 1.0))*y)
Normalize a 2D point to the range [0, 1].
Parameters:
- point (tuple): (x, y) coordinates of the point.
- width (int): Image or grid width.
- height (int): Image or grid height.
Returns:
- tuple: Normalized point (x / (width - 1), y / (height - 1)).
150def denormalize_point(x, y, width, height): 151 """ 152 Denormalize a 2D point from normalized coordinates back to pixel coordinates. 153 154 Parameters: 155 - point (tuple): Normalized (x, y) coordinates. 156 - width (int): Image or grid width. 157 - height (int): Image or grid height. 158 159 Returns: 160 - tuple: Denormalized point (x * (width - 1), y * (height - 1)). 161 """ 162 return (x * (width - 1.0), y * (height - 1.0))
Denormalize a 2D point from normalized coordinates back to pixel coordinates.
Parameters:
- point (tuple): Normalized (x, y) coordinates.
- width (int): Image or grid width.
- height (int): Image or grid height.
Returns:
- tuple: Denormalized point (x * (width - 1), y * (height - 1)).
166def numpy_info(numpy_array, should_print=True): 167 """ 168 Print and return basic statistical information about a NumPy array. 169 170 Computes common descriptive statistics such as mean, median, standard 171 deviation, variance, minimum, maximum, and array shape. This function is 172 primarily intended for quick debugging and inspection of intermediate 173 results in numerical or image-processing pipelines. 174 175 Parameters: 176 - numpy_array (np.ndarray): Input NumPy array to analyze. 177 - should_print (bool): If True, print the statistics to stdout. 178 179 Returns: 180 - str: A formatted string containing the computed statistics. 181 """ 182 result = "Array Statistics:" 183 result += f"\n - mean = {numpy_array.mean():.2f}" 184 result += f"\n - median = {np.median(numpy_array):.2f}" 185 # result += f"\n - percentile = {np.percentile(numpy_array, [25, 50, 75])}" 186 result += f"\n - std = {numpy_array.std():.2f}" 187 result += f"\n - var = {numpy_array.var():.2f}" 188 result += f"\n - min = {numpy_array.min():.2f}" 189 result += f"\n - max = {numpy_array.max():.2f}" 190 result += f"\n - shape = {numpy_array.shape}" 191 192 if should_print: 193 print(result) 194 return result
Print and return basic statistical information about a NumPy array.
Computes common descriptive statistics such as mean, median, standard deviation, variance, minimum, maximum, and array shape. This function is primarily intended for quick debugging and inspection of intermediate results in numerical or image-processing pipelines.
Parameters:
- numpy_array (np.ndarray): Input NumPy array to analyze.
- should_print (bool): If True, print the statistics to stdout.
Returns:
- str: A formatted string containing the computed statistics.
95def degree_to_vector(degree): 96 """ 97 Convert a degree angle to a 2D unit vector. 98 99 Parameters: 100 - degree (float): Angle in degrees. 101 102 Returns: 103 - list: 2D vector [cos(degree), sin(degree)]. 104 """ 105 # rad = math.radians(degree) 106 # return [math.cos(rad), math.sin(rad)] 107 rad = degree * _DEG2RAD 108 return (math.cos(rad), math.sin(rad))
Convert a degree angle to a 2D unit vector.
Parameters:
- degree (float): Angle in degrees.
Returns:
- list: 2D vector [cos(degree), sin(degree)].
113def vector_to_degree(x, y): 114 """ 115 Convert a 2D vector into its corresponding degree angle. 116 117 Parameters: 118 - vector (tuple): 2D vector (x, y). 119 120 Returns: 121 - int: Angle in degrees within the range [0, 360). 122 """ 123 # x, y = vector 124 # degree = math.degrees(math.atan2(y, x)) # atan2 returns angles between -180° and 180° 125 # return int( degree % 360 ) 126 deg = math.atan2(y, x) * _RAD2DEG 127 return int(deg % 360.0)
Convert a 2D vector into its corresponding degree angle.
Parameters:
- vector (tuple): 2D vector (x, y).
Returns:
- int: Angle in degrees within the range [0, 360).
131def normalize_point(x, y, width, height): 132 """ 133 Normalize a 2D point to the range [0, 1]. 134 135 Parameters: 136 - point (tuple): (x, y) coordinates of the point. 137 - width (int): Image or grid width. 138 - height (int): Image or grid height. 139 140 Returns: 141 - tuple: Normalized point (x / (width - 1), y / (height - 1)). 142 """ 143 # return (x / (width - 1), y / (height - 1)) 144 return ( (1.0 / (width - 1.0))*x, 145 (1.0 / (height - 1.0))*y)
Normalize a 2D point to the range [0, 1].
Parameters:
- point (tuple): (x, y) coordinates of the point.
- width (int): Image or grid width.
- height (int): Image or grid height.
Returns:
- tuple: Normalized point (x / (width - 1), y / (height - 1)).
150def denormalize_point(x, y, width, height): 151 """ 152 Denormalize a 2D point from normalized coordinates back to pixel coordinates. 153 154 Parameters: 155 - point (tuple): Normalized (x, y) coordinates. 156 - width (int): Image or grid width. 157 - height (int): Image or grid height. 158 159 Returns: 160 - tuple: Denormalized point (x * (width - 1), y * (height - 1)). 161 """ 162 return (x * (width - 1.0), y * (height - 1.0))
Denormalize a 2D point from normalized coordinates back to pixel coordinates.
Parameters:
- point (tuple): Normalized (x, y) coordinates.
- width (int): Image or grid width.
- height (int): Image or grid height.
Returns:
- tuple: Denormalized point (x * (width - 1), y * (height - 1)).