ModuleSupport
31class Support(ABC): 32 """Abstract base class for optics supports.""" 33 34 @abstractmethod 35 def _IncludeSupport(self, Point): 36 pass 37 38 @abstractmethod 39 def _get_grid(self, NbPoint, **kwargs): 40 pass 41 42 @abstractmethod 43 def _ContourSupport(self, Figure): 44 pass
Abstract base class for optics supports.
47class SupportRound(Support): 48 """ 49 A round support for optics. 50 51 Attributes 52 ---------- 53 radius : float 54 The radius of the support in mm. 55 """ 56 57 def __init__(self, Radius: float): 58 """ 59 Create a round support. 60 61 Parameters 62 ---------- 63 Radius : float 64 The radius of the support in mm. 65 66 """ 67 self.radius = Radius 68 69 def _IncludeSupport(self, Point): 70 """Return whether 2D-Point is within the rectangular Support.""" 71 return mgeo.IncludeDisk(self.radius, Point) 72 73 def _get_grid(self, NbPoint: int, **kwargs): 74 """ 75 Return a list of 2D-numpy-arrays with the coordinates a number NbPoints of points. 76 77 The points are distributed as a Vogel-spiral on the support, with the origin in the center of the support. 78 """ 79 MatrixXY = mgeo.SpiralVogel(NbPoint, self.radius) 80 ListCoordXY = [] 81 for k in range(NbPoint): 82 x = MatrixXY[k, 0] 83 y = MatrixXY[k, 1] 84 ListCoordXY.append(np.array([x, y])) 85 return ListCoordXY 86 87 def _ContourSupport(self, Figure): 88 """Draw support contour in MirrorProjection plots.""" 89 axe = Figure.add_subplot(111, aspect="equal") 90 axe.add_patch(patches.Circle((0, 0), self.radius, alpha=0.08)) 91 return axe 92 93 def _CircumRect(self): 94 return np.array([self.radius * 2, self.radius * 2]) 95 96 def _CircumCirc(self): 97 return self.radius 98 99 def _Contour_points(self, NbPoint=100, edges=False): 100 """ 101 Return a list of 2D-numpy-arrays with the coordinates a number NbPoints of points. 102 103 The points are distributed along the contour of the support so as to clearly define the edges. 104 The putpose is to use these points to draw a nicer mesh of the mirrors. 105 """ 106 return flatten_point_arrays(gen_circle_contour(self.radius, NbPoint), [], edges=edges)
A round support for optics.
Attributes
radius : float
The radius of the support in mm.
110class SupportRoundHole(Support): 111 """ 112 A round support for optics with a round hole. 113 114 Attributes 115 ---------- 116 radius : float 117 The radius of the support in mm. 118 119 radiushole : float 120 The radius of the hole in mm. 121 122 centerholeX : float 123 The x-cordinate of the hole's centre, in mm. 124 125 centerholeY : float 126 The y-cordinate of the hole's centre, in mm. 127 128 """ 129 130 def __init__(self, Radius: float, RadiusHole: float, CenterHoleX: float, CenterHoleY: float): 131 """ 132 Parameters 133 ---------- 134 Radius : float 135 The radius of the support in mm. 136 137 RadiusHole : float 138 The radius of the hole in mm. 139 140 CenterHoleX : float 141 The x-cordinate of the hole's centre, in mm. 142 143 CenterHoleY : float 144 The y-cordinate of the hole's centre, in mm. 145 146 """ 147 self.radius = Radius 148 self.radiushole = RadiusHole 149 self.centerholeX = CenterHoleX 150 self.centerholeY = CenterHoleY 151 152 def _IncludeSupport(self, Point): 153 """Returns whether 2D-Point is within the rectangular Support.""" 154 return mgeo.IncludeDisk(self.radius, Point) and not ( 155 mgeo.IncludeDisk(self.radiushole, Point - np.array([self.centerholeX, self.centerholeY, 0])) 156 ) 157 158 def _get_grid(self, NbPoint, **kwargs): 159 """ 160 Returns a list of 2D-numpy-arrays with the coordinates a number NbPoints of points, 161 distributed as a Vogel-spiral on the support, with the origin in the center of the support. 162 """ 163 MatrixXY = mgeo.SpiralVogel(NbPoint, self.radius) 164 ListCoordXY = [] 165 for k in range(NbPoint): 166 x = MatrixXY[k, 0] 167 y = MatrixXY[k, 1] 168 if (x - self.centerholeX) ** 2 + (y - self.centerholeY) ** 2 > self.radiushole**2: 169 ListCoordXY.append(np.array([x, y])) 170 return ListCoordXY 171 172 def _ContourSupport(self, Figure): 173 """Draws support contour in MirrorProjection plots.""" 174 axe = Figure.add_subplot(111, aspect="equal") 175 axe.add_patch(patches.Circle((0, 0), self.radius, alpha=0.08)) 176 axe.add_patch(patches.Circle((self.centerholeX, self.centerholeY), self.radiushole, color="white", alpha=1)) 177 return axe 178 179 def _CircumRect(self): 180 return np.array([self.radius * 2, self.radius * 2]) 181 182 def _CircumCirc(self): 183 return self.radius 184 185 def _Contour_points(self, NbPoint=100, edges=False): 186 """ 187 Return a list of 2D-numpy-arrays with the coordinates a number NbPoints of points. 188 189 The points are distributed along the contour of the support so as to clearly define the edges. 190 The putpose is to use these points to draw a nicer mesh of the mirrors. 191 """ 192 N_outer = int(round(NbPoint - NbPoint * self.radiushole / self.radius)) 193 outer = gen_circle_contour(self.radius, N_outer) 194 hole = gen_circle_contour(self.radiushole, NbPoint - N_outer) + np.array([self.centerholeX, self.centerholeY]) 195 return flatten_point_arrays(outer, [hole], edges=edges)
A round support for optics with a round hole.
Attributes
radius : float
The radius of the support in mm.
radiushole : float
The radius of the hole in mm.
centerholeX : float
The x-cordinate of the hole's centre, in mm.
centerholeY : float
The y-cordinate of the hole's centre, in mm.
130 def __init__(self, Radius: float, RadiusHole: float, CenterHoleX: float, CenterHoleY: float): 131 """ 132 Parameters 133 ---------- 134 Radius : float 135 The radius of the support in mm. 136 137 RadiusHole : float 138 The radius of the hole in mm. 139 140 CenterHoleX : float 141 The x-cordinate of the hole's centre, in mm. 142 143 CenterHoleY : float 144 The y-cordinate of the hole's centre, in mm. 145 146 """ 147 self.radius = Radius 148 self.radiushole = RadiusHole 149 self.centerholeX = CenterHoleX 150 self.centerholeY = CenterHoleY
Parameters
Radius : float The radius of the support in mm.
RadiusHole : float The radius of the hole in mm.
CenterHoleX : float The x-cordinate of the hole's centre, in mm.
CenterHoleY : float The y-cordinate of the hole's centre, in mm.
201class SupportRectangle(Support): 202 """ 203 A rectangular support for optics. 204 205 Attributes 206 ---------- 207 dimX : float 208 The dimension in mm along x. 209 210 dimY : float 211 The dimension in mm along y. 212 213 """ 214 215 def __init__(self, DimensionX: float, DimensionY: float): 216 """ 217 Parameters 218 ---------- 219 DimensionX : float 220 The dimension in mm along x. 221 222 DimensionY : float 223 The dimension in mm along y. 224 225 """ 226 self.dimX = DimensionX 227 self.dimY = DimensionY 228 229 def _IncludeSupport(self, Point: np.ndarray) -> bool: 230 """Return whether 2D-Point is within the rectangular Support.""" 231 return mgeo.IncludeRectangle(self.dimX, self.dimY, Point) 232 233 def _get_grid(self, NbPoints: int, **kwargs) -> list[np.ndarray]: 234 """ 235 Returns a list of 2D-numpy-arrays with the coordinates a number NbPoints of points, 236 distributed as a regular grid on the support, with the origin in the center of the support. 237 """ 238 nbx = int( 239 np.sqrt(self.dimX / self.dimY * NbPoints + 0.25 * (self.dimX - self.dimY) ** 2 / self.dimY**2) 240 - 0.5 * (self.dimX - self.dimY) / self.dimY 241 ) 242 nby = int(NbPoints / nbx) 243 x = np.linspace(-self.dimX / 2, self.dimX / 2, nbx) 244 y = np.linspace(-self.dimY / 2, self.dimY / 2, nby) 245 ListCoordXY = [] 246 for i in x: 247 for j in y: 248 ListCoordXY.append(np.array([i, j])) 249 return ListCoordXY 250 251 def _ContourSupport(self, Figure): 252 """Draws support contour in MirrorProjection plots.""" 253 axe = Figure.add_subplot(111, aspect="equal") 254 axe.add_patch(patches.Rectangle((-self.dimX * 0.5, -self.dimY * 0.5), self.dimX, self.dimY, alpha=0.08)) 255 return axe 256 257 def _CircumRect(self): 258 return np.array([self.dimX, self.dimY]) 259 260 def _CircumCirc(self): 261 return np.sqrt(self.dimX**2 + self.dimY**2) / 2 262 263 def _Contour_points(self, NbPoint=100, edges=False): 264 """ 265 Return a list of 2D-numpy-arrays with the coordinates a number NbPoints of points. 266 267 The points are distributed along the contour of the support so as to clearly define the edges. 268 The putpose is to use these points to draw a nicer mesh of the mirrors. 269 """ 270 return flatten_point_arrays(gen_rectangle_contour(self.dimX, self.dimY, NbPoint), [], edges=edges)
A rectangular support for optics.
Attributes
dimX : float
The dimension in mm along x.
dimY : float
The dimension in mm along y.
215 def __init__(self, DimensionX: float, DimensionY: float): 216 """ 217 Parameters 218 ---------- 219 DimensionX : float 220 The dimension in mm along x. 221 222 DimensionY : float 223 The dimension in mm along y. 224 225 """ 226 self.dimX = DimensionX 227 self.dimY = DimensionY
Parameters
DimensionX : float The dimension in mm along x.
DimensionY : float The dimension in mm along y.
274class SupportRectangleHole(Support): 275 """ 276 A rectangular support for optics with a round hole. 277 278 Attributes 279 ---------- 280 dimX : float 281 The dimension in mm along x. 282 283 dimY : float 284 The dimension in mm along y. 285 286 radiushole : float 287 The radius of the hole in mm. 288 289 centerholeX : float 290 The x-cordinate of the hole's centre, in mm. 291 292 centerholeY : float 293 The y-cordinate of the hole's centre, in mm. 294 295 """ 296 297 def __init__(self, DimensionX: float, DimensionY: float, RadiusHole: float, CenterHoleX: float, CenterHoleY: float): 298 """ 299 Parameters 300 ---------- 301 DimensionX : float 302 The dimension in mm along x. 303 304 DimensionY : float 305 The dimension in mm along y. 306 307 RadiusHole : float 308 The radius of the hole in mm. 309 310 CenterHoleX : float 311 The x-cordinate of the hole's centre, in mm. 312 313 CenterHoleY : float 314 The y-cordinate of the hole's centre, in mm. 315 316 """ 317 self.dimX = DimensionX 318 self.dimY = DimensionY 319 self.radiushole = RadiusHole 320 self.centerholeX = CenterHoleX 321 self.centerholeY = CenterHoleY 322 323 def _IncludeSupport(self, Point): 324 """Returns whether 2D-Point is within the rectangular Support.""" 325 return mgeo.IncludeRectangle(self.dimX, self.dimY, Point) and not ( 326 mgeo.IncludeDisk(self.radiushole, Point - np.array([self.centerholeX, self.centerholeY, 0])) 327 ) 328 329 def _get_grid(self, NbPoint, **kwargs): 330 """ 331 Returns a list of 2D-numpy-arrays with the coordinates a number NbPoints of points, 332 distributed as a regular grid on the support, with the origin in the center of the support. 333 """ 334 x = np.linspace(-self.dimX / 2, self.dimX / 2, int(self.dimX / self.dimY * np.sqrt(NbPoint))) 335 y = np.linspace(-self.dimY / 2, self.dimY / 2, int(self.dimY / self.dimX * np.sqrt(NbPoint))) 336 337 ListCoordXY = [] 338 for i in x: 339 for j in y: 340 if (i - self.centerholeX) ** 2 + (j - self.centerholeY) ** 2 > self.radiushole**2: 341 ListCoordXY.append(np.array([i, j])) 342 return ListCoordXY 343 344 def _ContourSupport(self, Figure): 345 """Draws support contour in MirrorProjection plots.""" 346 axe = Figure.add_subplot(111, aspect="equal") 347 axe.add_patch(patches.Rectangle((-self.dimX * 0.5, -self.dimY * 0.5), self.dimX, self.dimY, alpha=0.08)) 348 axe.add_patch(patches.Circle((self.centerholeX, self.centerholeY), self.radiushole, color="white", alpha=1)) 349 return axe 350 351 def _CircumRect(self): 352 return np.array([self.dimX, self.dimY]) 353 354 def _CircumCirc(self): 355 return np.sqrt(self.dimX**2 + self.dimY**2) / 2 356 357 def _Contour_points(self, NbPoint=100, edges=False): 358 """ 359 Return a list of 2D-numpy-arrays with the coordinates a number NbPoints of points. 360 361 The points are distributed along the contour of the support so as to clearly define the edges. 362 The putpose is to use these points to draw a nicer mesh of the mirrors. 363 """ 364 outer_length = 2 * (self.dimX + self.dimY) 365 hole_length = 2 * np.pi * self.radiushole 366 total_length = outer_length + hole_length 367 NbHole = int(round(hole_length / total_length * NbPoint)) 368 outer = gen_rectangle_contour(self.dimX, self.dimY, NbPoint - NbHole) 369 hole = gen_circle_contour(self.radiushole, NbHole) + np.array([self.centerholeX, self.centerholeY]) 370 return flatten_point_arrays(outer, [hole], edges=edges)
A rectangular support for optics with a round hole.
Attributes
dimX : float
The dimension in mm along x.
dimY : float
The dimension in mm along y.
radiushole : float
The radius of the hole in mm.
centerholeX : float
The x-cordinate of the hole's centre, in mm.
centerholeY : float
The y-cordinate of the hole's centre, in mm.
297 def __init__(self, DimensionX: float, DimensionY: float, RadiusHole: float, CenterHoleX: float, CenterHoleY: float): 298 """ 299 Parameters 300 ---------- 301 DimensionX : float 302 The dimension in mm along x. 303 304 DimensionY : float 305 The dimension in mm along y. 306 307 RadiusHole : float 308 The radius of the hole in mm. 309 310 CenterHoleX : float 311 The x-cordinate of the hole's centre, in mm. 312 313 CenterHoleY : float 314 The y-cordinate of the hole's centre, in mm. 315 316 """ 317 self.dimX = DimensionX 318 self.dimY = DimensionY 319 self.radiushole = RadiusHole 320 self.centerholeX = CenterHoleX 321 self.centerholeY = CenterHoleY
Parameters
DimensionX : float The dimension in mm along x.
DimensionY : float The dimension in mm along y.
RadiusHole : float The radius of the hole in mm.
CenterHoleX : float The x-cordinate of the hole's centre, in mm.
CenterHoleY : float The y-cordinate of the hole's centre, in mm.
374class SupportRectangleRectHole(Support): 375 """ 376 A rectangular support for optics, with a rectangular hole. 377 378 Attributes 379 ---------- 380 dimX : float 381 The dimension in mm along x. 382 383 dimY : float 384 The dimension in mm along y. 385 386 holeX : float 387 The dimension of the hole in mm along x. 388 389 holeY : float 390 The dimension of the hole in mm along y. 391 392 centerholeX : float 393 The x-cordinate of the hole's centre, in mm. 394 395 centerholeY : float 396 The y-cordinate of the hole's centre, in mm. 397 398 """ 399 400 def __init__( 401 self, DimensionX: float, DimensionY: float, HoleX: float, HoleY: float, CenterHoleX: float, CenterHoleY: float 402 ): 403 """ 404 Parameters 405 ---------- 406 DimensionX : float 407 The dimension in mm along x. 408 409 DimensionY : float 410 The dimension in mm along y. 411 412 HoleX : float 413 The dimension of the hole in mm along x. 414 415 HoleY : float 416 The dimension of the hole in mm along y. 417 418 CenterHoleX : float 419 The x-cordinate of the hole's centre, in mm. 420 421 CenterHoleY : float 422 The y-cordinate of the hole's centre, in mm. 423 424 """ 425 self.dimX = DimensionX 426 self.dimY = DimensionY 427 self.holeX = HoleX 428 self.holeY = HoleY 429 self.centerholeX = CenterHoleX 430 self.centerholeY = CenterHoleY 431 432 def _IncludeSupport(self, Point): 433 """Return whether 2D-Point is within the rectangular Support.""" 434 return mgeo.IncludeRectangle(self.dimX, self.dimY, Point) and not mgeo.IncludeRectangle( 435 self.holeX, self.holeY, Point - np.array([self.centerholeX, self.centerholeY, 0]) 436 ) 437 438 def _get_grid(self, NbPoint, **kwargs): 439 """ 440 Returns a list of 2D-numpy-arrays with the coordinates a number NbPoints of points, 441 distributed as a regular grid on the support, with the origin in the center of the support. 442 """ 443 nbx = int( 444 np.sqrt(self.dimX / self.dimY * NbPoint + 0.25 * (self.dimX - self.dimY) ** 2 / self.dimY**2) 445 - 0.5 * (self.dimX - self.dimY) / self.dimY 446 ) 447 nby = int(NbPoint / nbx) 448 x = np.linspace(-self.dimX / 2, self.dimX / 2, nbx) 449 y = np.linspace(-self.dimY / 2, self.dimY / 2, nby) 450 451 ListCoordXY = [] 452 for i in x: 453 for j in y: 454 if abs(i - self.centerholeX) > self.holeX / 2 or abs(j - self.centerholeY) > self.holeY / 2: 455 ListCoordXY.append(np.array([i, j])) 456 return ListCoordXY 457 458 def _ContourSupport(self, Figure): 459 """Draws support contour in MirrorProjection plots.""" 460 axe = Figure.add_subplot(111, aspect="equal") 461 axe.add_patch(patches.Rectangle((-self.dimX * 0.5, -self.dimY * 0.5), self.dimX, self.dimY, alpha=0.08)) 462 axe.add_patch( 463 patches.Rectangle( 464 (-self.holeX * 0.5 + self.centerholeX, -self.holeY * 0.5 + self.centerholeY), 465 self.holeX, 466 self.holeY, 467 color="white", 468 alpha=1, 469 ) 470 ) 471 return axe 472 473 def _CircumRect(self): 474 return np.array([self.dimX, self.dimY]) 475 476 def _CircumCirc(self): 477 return np.sqrt(self.dimX**2 + self.dimY**2) / 2 478 479 def _Contour_points(self, NbPoint=100, edges=False): 480 """ 481 Return a list of 2D-numpy-arrays with the coordinates a number NbPoints of points. 482 483 The points are distributed along the contour of the support so as to clearly define the edges. 484 The putpose is to use these points to draw a nicer mesh of the mirrors. 485 """ 486 outer_length = 2 * (self.dimX + self.dimY) 487 hole_length = 2 * (self.holeX + self.holeY) 488 total_length = outer_length + hole_length 489 NbHole = int(round(hole_length / total_length * NbPoint)) 490 outer = gen_rectangle_contour(self.dimX, self.dimY, NbPoint - NbHole) 491 hole = gen_rectangle_contour(self.holeX, self.holeY, NbHole) + np.array([self.centerholeX, self.centerholeY]) 492 return flatten_point_arrays(outer, [hole[::-1]], edges=edges)
A rectangular support for optics, with a rectangular hole.
Attributes
dimX : float
The dimension in mm along x.
dimY : float
The dimension in mm along y.
holeX : float
The dimension of the hole in mm along x.
holeY : float
The dimension of the hole in mm along y.
centerholeX : float
The x-cordinate of the hole's centre, in mm.
centerholeY : float
The y-cordinate of the hole's centre, in mm.
400 def __init__( 401 self, DimensionX: float, DimensionY: float, HoleX: float, HoleY: float, CenterHoleX: float, CenterHoleY: float 402 ): 403 """ 404 Parameters 405 ---------- 406 DimensionX : float 407 The dimension in mm along x. 408 409 DimensionY : float 410 The dimension in mm along y. 411 412 HoleX : float 413 The dimension of the hole in mm along x. 414 415 HoleY : float 416 The dimension of the hole in mm along y. 417 418 CenterHoleX : float 419 The x-cordinate of the hole's centre, in mm. 420 421 CenterHoleY : float 422 The y-cordinate of the hole's centre, in mm. 423 424 """ 425 self.dimX = DimensionX 426 self.dimY = DimensionY 427 self.holeX = HoleX 428 self.holeY = HoleY 429 self.centerholeX = CenterHoleX 430 self.centerholeY = CenterHoleY
Parameters
DimensionX : float The dimension in mm along x.
DimensionY : float The dimension in mm along y.
HoleX : float The dimension of the hole in mm along x.
HoleY : float The dimension of the hole in mm along y.
CenterHoleX : float The x-cordinate of the hole's centre, in mm.
CenterHoleY : float The y-cordinate of the hole's centre, in mm.
495def find_hull(points): 496 # start from leftmost point 497 current_point = min(range(len(points)), key=lambda i: points[i][0]) 498 # initialize hull with current point 499 hull = [current_point] 500 # initialize list of linked points 501 linked = [] 502 # continue until all points have been linked 503 while len(linked) < len(points) - 1: 504 # initialize minimum distance and closest point 505 min_distance = math.inf 506 closest_point = None 507 # find closest unlinked point to current point 508 for i, point in enumerate(points): 509 if i not in linked: 510 distance = math.dist(points[current_point], point) 511 if distance < min_distance: 512 min_distance = distance 513 closest_point = i 514 # add closest point to hull and linked list 515 hull.append(closest_point) 516 linked.append(closest_point) 517 # update current point 518 current_point = closest_point 519 # add link between last point and first point 520 hull.append(hull[0]) 521 # convert hull to a list of pairs of indices 522 indices = [[hull[i], hull[i + 1]] for i in range(len(hull) - 1)] 523 return indices
526def gen_rectangle_contour(dimX, dimY, NbPoints): 527 # calculate number of points on each side 528 nX = math.ceil(dimX / (dimX + dimY) * NbPoints) 529 nY = NbPoints - nX 530 # calculate distance between points on each side 531 dX = dimX / (nX - 1) 532 dY = dimY / (nY - 1) 533 # generate points on top side 534 top_points = [(i * dX - dimX / 2, dimY / 2) for i in range(nX)] 535 # generate points on right side 536 right_points = [(dimX / 2, dimY / 2 - i * dY) for i in range(1, nY)] 537 # generate points on bottom side 538 bottom_points = [(dimX / 2 - i * dX, -dimY / 2) for i in range(1, nX)] 539 # generate points on left side 540 left_points = [(-dimX / 2, -dimY / 2 + i * dY) for i in range(1, nY - 1)] 541 # concatenate points in counterclockwise order 542 points = top_points + right_points + bottom_points + left_points 543 return np.array(points)
554def flatten_point_arrays(outer, holes=[], edges=False): 555 coords = [i for i in outer] 556 edges_list = [] 557 offset = len(coords) 558 for arr in holes: 559 # add coordinates to list 560 coords.extend(arr) 561 # add edges to list 562 if edges: 563 n = arr.shape[0] 564 edge_indices = np.arange(n) 565 edge_indices += offset 566 edges_list += [edge_indices.T.tolist() + [offset]] 567 # update offset 568 offset += arr.shape[0] 569 if edges: 570 return coords, edges_list 571 else: 572 return coords