Surface¶
- class diffinytrace.surface.Surface[source]¶
Bases:
SemiFunctionalModuleWhile we all have an intuitive idea of what curves and surfaces are, we need a mathematically accurate definition from which we can proceed to illustrate how different types of algorithms are implemented. In the following, we will introduce three common ways of describing curves and surfaces.
1. Parametric Equations Parametric curves are functions that map a single variable \(\theta\) (the parameter) to a vector in \(\mathbb{R}^2\). Thus, such curves are referred to as parametrized or parametrically defined curves (see [GVJ+09]). The variable \(\theta\) is an element of the parametric domain of the parametric curve (see [CHB09]). For example, a circle can be described with the parametric domain \([0, 2\pi]\) and the function \(f: [0, 2\pi] \mapsto \mathbb{R}^2\),
\[\begin{split}f(\theta) = \begin{bmatrix} \cos \theta \\ \sin \theta \end{bmatrix}.\end{split}\]Similarly, parametric surfaces can be described by a function that maps from a two-dimensional parametric domain to \(\mathbb{R}^3\) (see [GVJ+09]).
2. Explicit Equations Curves and surfaces can also be expressed using explicit equations. When describing a curve with explicit equations, an explicit function \(f: \mathbb{R} \to \mathbb{R}\) of the form \(y = f(x)\) assigns a unique value of \(y\) to each \(x \in \mathbb{R}\). The values of \(y\) can then be seen as a description of the curve. Unfortunately, it is not possible to describe all curves and surfaces with this method. For example, considering the unit circle, only one semicircle can be represented at a time using explicit equations such as:
\[y = \sqrt{1 - x^2} \quad \text{or} \quad y = -\sqrt{1 - x^2}.\]Similarly, three-dimensional surfaces can be described explicitly using functions of the form \(y = f(x_1, x_2)\), which assign a unique \(y\)-value to each pair of \((x_1, x_2)\)-coordinates (see [GVJ+09]).
3. Implicit Equations A planar curve is defined implicitly, or in Cartesian coordinates, when it is described as the set of solutions to an equation involving two variables, typically expressed as \(f(y_1, y_2) = 0\). For example, the equation
\[y_1^2 + y_2^2 - 1 = 0\]represents an implicit unit circle in \(\mathbb{R}^2\). Similarly, an implicit surface can be expressed with an equation in the form of (see [GVJ+09]):
\[f(y_1, y_2, y_3) = 0.\]Optical Surfaces In our ray tracer, we use a less general description of the surfaces. We will call surfaces relevant for ray tracing optical surfaces. Every optical surface is composed of an explicit surface \(\hat{S}: \mathbb{R}^2 \mapsto \mathbb{R}\) and a transformation matrix \(M \in \mathbb{R}^{4 \times 4}\). In the following, we will state the implicit surface description for the ray tracer itself and the parametric surface description for plots and constraint optimization.
1. Implicit Surface Description Here, surfaces are described implicitly by the equation \(s(\hat{y}) = 0\). The function \(s\) is composed of the explicit description \(\hat{S}(\hat{x}_1, \hat{x}_2)\) and an affine transformation matrix \(M\) as follows:
\[\begin{split}\begin{bmatrix} \hat{x} \\ 1 \end{bmatrix} = M^{-1} \begin{bmatrix} \hat{y} \\ 1 \end{bmatrix}^T\end{split}\]\[s(\hat{y}) = \hat{S}(\hat{x}_1(\hat{y}), \hat{x}_2(\hat{y})) - \hat{x}_3(\hat{y})\]This description allows us to calculate ray-surface intersections efficiently. Typically, we do not state \(M^{-1}\) explicitly in the implementation but simply apply the transformation itself directly.
2. Parametric Surface Description In this approach, surfaces are defined by parameterizing coordinates. For optical surfaces, the surface is described again as a composition of the explicit description \(\hat{S}\) and a transformation matrix \(M\) as follows:
\[\begin{split}\begin{bmatrix} S(\hat{x}_1, \hat{x}_2) \\ 1 \end{bmatrix} = M \begin{bmatrix} \hat{x}_1 \\ \hat{x}_2 \\ \hat{S}(\hat{x}_1, \hat{x}_2) \\ 1 \end{bmatrix}\end{split}\]In our library, the parametric domains are defined by the lenses or target surfaces (detectors). For example, in the case of a round lens, the parametric domain would be the disc determined by the aperture radius. This surface description is typically used for plotting but is also useful in the context of constraint optimization.
Examples
>>> import diffinytrace as dit >>> aperture_radius = 30. >>> lens_thickness = 8. >>> material = dit.materials["NBK7"] >>> transform = dit.transforms.Identity() >>> asphere = dit.Aspheric(1./40., 0.0, [-0.00001]) >>> plane = dit.Plane() >>> lens = dit.Lens(transform, lens_thickness, >>> asphere, plane, >>> material, aperture_radius) >>> dit.plotting.system2D.plot(lens)
- class diffinytrace.surface.Plane[source]¶
Bases:
SurfaceA class to represent a plane surface in 3D space. The plane is defined by the equation z = 0, and the functional method returns the z-coordinate of the input points.
- class diffinytrace.surface.Aspheric(curvature, conic_coeff=None, aspheric_param=None)[source]¶
Bases:
SurfaceThis is the aspheric surface class, implementation follows: https://en.wikipedia.org/wiki/Aspheric_lens.
The surface is parameterized as an implicit function \(f(x, y, z) = 0\). For simplicity, we assume the surface function \(f(x, y, z)\) can be decomposed as:
\[f(x, y, z) = g(x, y) + h(z),\]where \(g(x, y)\) and \(h(z)\) are explicit functions:
\[r^2 = x^2 + y^2\]\[g(x, y) = \frac{c \cdot r^2}{1 + \sqrt{1 - (1 + k) \cdot \frac{r^2}{R^2}}} + a_0 \cdot r^4 + a_1 \cdot r^6 + \cdots\]\[h(z) = -z\]- Parameters:
c (float) – Surface curvature, or one over the radius of curvature.
k (float) – Conic coefficient.
ai (list or None) – Aspheric parameters, could be a vector. When None, the surface is spherical.
- static g(x: Tensor, y: Tensor, curvature: Tensor, conic_coeff: Tensor, aspheric_param: Tensor | None) Tensor[source]¶
- static h(z: Tensor, curvature: Tensor, conic_coeff: Tensor, aspheric_param: Tensor | None) Tensor[source]¶
- static functional(O: Tensor, curvature: Tensor, conic_coeff: Tensor, aspheric_param: Tensor | None) Tensor[source]¶
This method provides the implicit surface description. It is a static method. Diffinytrace constructs a function s(R, p) on the fly to describe the surface, allowing better control over derivative calculations.
- class diffinytrace.surface.Bspline(aperture_radius: float, orders: List[int], ns: List[int])[source]¶
Bases:
SurfaceA class to represent a B-spline surface in 3D space. The surface is defined by the B-spline basis functions and control points. The functional method returns the z-coordinate of the input points.
- get_CAD_coeff(affine_transform: Transform) ndarray[source]¶
Get the CAD coefficients from the affine transform.
- Parameters:
affine_transform (torch.Tensor) – Affine transformation matrix.
- Returns:
Control points of the B-spline surface.
- Return type:
numpy.ndarray
- get_CAD_face(affine_transform)[source]¶
Get the CAD face from the affine transform.
- Parameters:
affine_transform (torch.Tensor) – Affine transformation matrix.
- Returns:
CAD face object.
- refine()[source]¶
Refine the B-spline surface by increasing the number of control points. The number of control points is increased by 1 in each direction.
- class diffinytrace.surface.Legendre(aperture_radius: float, degree: int)[source]¶
Bases:
SurfaceA class to represent a Legendre surface in 3D space. Its kinda work in progress.