@@ -33,9 +33,9 @@ class geometry:
33
33
If kappa is None then the surface is planar.
34
34
kappa < 0 -> hyperboloid
35
35
kappa = 0 -> paraboloid
36
- 0 < kappa < 1 -> hemelipsoid of revolution about major axis
36
+ 0 < kappa < 1 -> helioid of revolution about major axis
37
37
kappa = 1 -> hemisphere
38
- kappa > 1 -> hemelipsoid of revolution about minor axis
38
+ kappa > 1 -> helioid of revolution about minor axis
39
39
c (optional): float/int
40
40
Vertex curvature of the surface.
41
41
If c is 0 then the surface is planar.
@@ -82,27 +82,42 @@ def check_params(self) -> None:
82
82
Note that this does not affect the calculation since c is 0.
83
83
84
84
"""
85
-
86
85
if self .c != 0 :
87
86
if self .kappa is None :
88
87
raise Exception ("Specify a kappa for this conic." )
89
- elif self .kappa > 0 :
88
+ elif self .kappa > 0 :
90
89
print ("Warning: Specified c value is not used when kappa>0" )
91
- self .c = np .sqrt (1 / (self .kappa * pow (self .Diam / 2. ,2 )))
90
+ self .c = np .sqrt (1 / (self .kappa * pow (self .Diam / 2. , 2 )))
92
91
elif self .c == 0 and self .kappa is None :
93
- #Used for planes, does not affect calculations.
92
+ # Used for planes, does not affect calculations.
94
93
self .kappa = 1.
95
94
96
95
def get_surface (self , point : np .ndarray ) -> Tuple [float , List [float ]]:
97
- """ Returns the function and derivitive of a surface for a point. """
96
+ """ Returns the function and derivative of a surface for a point. """
98
97
return self .conics (point )
99
98
100
99
def get_surface_plot (self , points : np .ndarray ) -> np .ndarray :
101
100
""" Returns the function value for an array of points. """
102
101
return self .conics_plot (points )
103
102
103
+ def get_surface_vector (self , points : np .ndarray ) -> Tuple [np .ndarray , np .ndarray ]:
104
+ """Returns function values and derivative vectors for an array of points.
105
+
106
+ Parameters
107
+ ----------
108
+ points : np.ndarray of shape (N,3)
109
+ Array of points.
110
+ Returns
111
+ -------
112
+ func : np.ndarray of shape (N,)
113
+ Function values.
114
+ deriv : np.ndarray of shape (N,3)
115
+ Derivative vectors.
116
+ """
117
+ return self .conics_vector (points )
118
+
104
119
def conics (self , point : np .ndarray ) -> Tuple [float , List [float ]]:
105
- """Returns function value and derivitive list for conics and sphere surfaces.
120
+ """Returns function value and derivative list for conics and sphere surfaces.
106
121
107
122
Note
108
123
----
@@ -122,25 +137,58 @@ def conics(self, point: np.ndarray) -> Tuple[float, List[float]]:
122
137
function : float
123
138
Function value of the surface. A value of 0 corresponds to the ray intersecting
124
139
the surface.
125
- derivitive : list of length 3
126
- Function derivitive of the surface at the point given. Used to determine which
127
- direction the ray needs to travel in and the step size to intersect the surface.
128
-
140
+ derivative : list of length 3
141
+ Derivative of the surface at the point given.
129
142
"""
130
-
131
- X ,Y ,Z = point
132
- rho = np .sqrt (pow (X ,2 ) + pow (Y , 2 ))
133
- if rho > self .Diam / 2. or rho < self .diam / 2. :
143
+ X , Y , Z = point
144
+ rho = np .sqrt (pow (X , 2 ) + pow (Y , 2 ))
145
+ if rho > self .Diam / 2. or rho < self .diam / 2. :
134
146
raise NotOnSurfaceError ()
135
- # Ensure kappa is not None before using it in calculations
136
147
if self .kappa is None :
137
148
raise ValueError ("kappa must not be None for conic calculations" )
138
- #Conic equation.
139
- function = Z - self .c * pow (rho , 2 )/ (1 + pow ((1 - self .kappa * pow (self .c , 2 )* pow (rho ,2 )), 0.5 ))
140
- #See Spencer, Murty section on rotational surfaces for definition of E.
141
- E = self .c / pow ((1 - self .kappa * pow (self .c , 2 )* pow (rho ,2 )), 0.5 )
142
- derivitive = [- X * E , - Y * E , 1. ]
143
- return function , derivitive
149
+ function = Z - self .c * pow (rho , 2 ) / (1 + pow ((1 - self .kappa * pow (self .c , 2 ) * pow (rho , 2 )), 0.5 ))
150
+ E = self .c / pow ((1 - self .kappa * pow (self .c , 2 ) * pow (rho , 2 )), 0.5 )
151
+ derivative = [- X * E , - Y * E , 1. ]
152
+ return function , derivative
153
+
154
+ def conics_vector (self , points : np .ndarray ) -> Tuple [np .ndarray , np .ndarray ]:
155
+ """Returns function values and derivative vectors for conics and sphere surfaces.
156
+
157
+ Vectorized version for an array of points.
158
+
159
+ Parameters
160
+ ----------
161
+ points : np.ndarray of shape (N,3)
162
+ Array of points (X, Y, Z).
163
+
164
+ Returns
165
+ -------
166
+ func : np.ndarray of shape (N,)
167
+ Function values for each point.
168
+ deriv : np.ndarray of shape (N,3)
169
+ Derivative vectors for each point.
170
+ """
171
+ X = points [:, 0 ]
172
+ Y = points [:, 1 ]
173
+ Z = points [:, 2 ]
174
+ rho = np .sqrt (X ** 2 + Y ** 2 )
175
+ # Initialize outputs
176
+ func = np .full (points .shape [0 ], np .nan )
177
+ deriv = np .full ((points .shape [0 ], 3 ), np .nan )
178
+ # Determine valid indices based on aperture
179
+ valid = (rho <= self .Diam / 2. ) & (rho >= self .diam / 2. )
180
+ if self .kappa is None :
181
+ raise ValueError ("kappa must not be None for conic calculations" )
182
+ # Calculate for valid points
183
+ rho_valid = rho [valid ]
184
+ sqrt_term = np .sqrt (1 - self .kappa * self .c ** 2 * rho_valid ** 2 )
185
+ denom = 1 + sqrt_term
186
+ func [valid ] = Z [valid ] - self .c * rho_valid ** 2 / denom
187
+ E = self .c / sqrt_term
188
+ deriv [valid , 0 ] = - X [valid ] * E
189
+ deriv [valid , 1 ] = - Y [valid ] * E
190
+ deriv [valid , 2 ] = 1.
191
+ return func , deriv
144
192
145
193
def conics_plot (self , point : np .ndarray ) -> np .ndarray :
146
194
"""Returns Z values for an array of points for plotting conics.
@@ -154,18 +202,14 @@ def conics_plot(self, point: np.ndarray) -> np.ndarray:
154
202
-------
155
203
function : 1d np.array
156
204
np.array of Z values for each X,Y pair.
157
-
158
205
"""
159
-
160
- X , Y = point [:,0 ], point [:,1 ]
161
- rho = np .sqrt (pow (X ,2 ) + pow (Y ,2 ))
162
- #Initialize Z value array
206
+ X , Y = point [:, 0 ], point [:, 1 ]
207
+ rho = np .sqrt (pow (X , 2 ) + pow (Y , 2 ))
163
208
function = np .zeros (len (point ))
164
- nan_idx = (rho > self .Diam / 2. ) + (rho < self .diam / 2. )
165
- rho = np .sqrt (pow (X [~ nan_idx ],2 ) + pow (Y [~ nan_idx ], 2 ))
209
+ nan_idx = (rho > self .Diam / 2. ) + (rho < self .diam / 2. )
210
+ rho = np .sqrt (pow (X [~ nan_idx ], 2 ) + pow (Y [~ nan_idx ], 2 ))
166
211
function [nan_idx ] = np .nan
167
- # Ensure kappa is not None before using it in calculations
168
212
if self .kappa is None :
169
213
raise ValueError ("kappa must not be None for conic plot calculations" )
170
- function [~ nan_idx ] = self .c * pow (rho , 2 )/ (1 + pow ((1 - self .kappa * pow (self .c , 2 )* pow (rho ,2 )), 0.5 ))
214
+ function [~ nan_idx ] = self .c * pow (rho , 2 ) / (1 + pow ((1 - self .kappa * pow (self .c , 2 ) * pow (rho , 2 )), 0.5 ))
171
215
return function
0 commit comments