In non-sequential mode, ZEMAX allows us to use different objects in the design such as lenses, aspheres, cylinders, blocks, and other objects. A system feature also allows the user to create a custom object, if needed.
The “User Defined Object” in the object type list can be represented by a Dynamic Link Library (DLL) and written using C programming. The advantages of these objects as described in [1] include:
• DLL-defined objects generally ray trace much faster, and with much higher numerical precision than objects imported from CAD programs.
• Unlike the polygon object which only has flat faces, any number of complex curved shapes may be combined in a single object.
• Objects may have a mixture of reflective and refractive curved faces, with user-defined face names.
• The DLL description is inherently parametric, which means the object is dynamically regenerated when any defining property is modified. This allows interactive design modification and optimization.
• User-defined coating data, including detailed control over the complex amplitude reflection and transmission coefficients is supported. Coating data may be ray position-, cosine-, or object coordinate-dependent.
Most objects in optical design are rotationally symmetric. We’ll explore below some user-defined objects with a surface of revolution of Bezier curve and a surface of revolution of cubic spline curve. These curves were chosen because they can be nonstandard and free form. Moreover, their description with a set of points allows the user to control the object shape more efficiently. We will also give the mathematics for calculating the ray-surface intersection. This type of free form object can be used for designing LED collimating optics, lightpipes, and other illumination applications.

Two sample user DLLs and C code files can be found in \ZEMAX\Object\Dll\UserObjects: Half cylinder and Elliptical volume. These DLLs create the solid bodies shown below.
Each object has flat front and rear surfaces, and a user-defined side surface. For each user- defined object, we must (1) describe its visual appearance and (2) organize it for ray trace. Each surface can be represented by a set of flat triangular facets. This approximation is used for ZEMAX object drawing layouts and gives the starting point for finding the ray-surface intersection point, as will be described further.
For raytracing to non-flat surfaces, you must find the ray with surface intersection point and the normal vector to the surface at this point. This is done for each object surface. The algorithms for those calculations depend on the surface representation: parametric form, implicit form, or flat surface. If the surface is flat however, raytracing is only needed using facets. In ZEMAX sample DLLs code, information regarding C language routines and details, as well as comments about ZEMAX and DLL exchange data, is available.
Most surfaces can be represented in implicit form by F(x,y,z) = 0. As described in book [2], the normal vector N to surface at point (x0,y0,z0) is proportional to partial derivatives of F(x,y,z) at this point. The normal vector is:![]()
ZEMAX gives the point of intersection ray with flat facet (x1,y1,z1) and the direction cosines of ray (l,m,n), while the user provides distance t from point (x1,y1,z1) to actual surface ray intersection point (x0,y0,z0) and the normal vector components.
Ray equations are xR = x1 + lt, yR = y1 + mt, zR = z1 + nt. At the intersection point, F(x1 + lt, y1 + mt, z1 + nt) = F(t) = 0 (one variable equation). The following Newton algorithm can be used to solve it:
where tk+1 is the next approximation for t. If |tk - tk+1| < e, where e is a user-defined small number, the equation is solved (more complex iterators may be needed for more complex surface shapes). A variable t derivative can be written as:![]()
Note: vector components must be normalized before sending to ZEMAX.
In a Cartesian coordinate system, any implicit curve can be easily rotated about the z-axis. The equation curve y = f(z) describes the curve. When rotated, the surface of revolution is assumed to be a set of round circumferences along the z-axis, with radii Ri = f(z). The circle equation is R2 = x2 + y2 and the surface of revolution is F(x,y,z) = f(z)2 - x2 - y2 = 0.
As an example, let’s use a cubic spline curve. A cubic spline is a piecewise curve with y = f(x), which interpolates any smooth curve defined by the set of points (the curve is through a set of points S = {(x1,y1) ... (xN,yN)}). Each piece of cubic spline is a cubic polynomial and lays between two neighboring points: (xi+1,yi+1) and (xi,yi). Note that x point values must be placed in ascending order, i.e. xi < xi+1. The disadvantage of cubic splines is that they are inclined to oscillation in the neighborhood of the point if it is considerably different from its neighbors. More information can be found in [5], other literature, and on the web.
Below, the shown object is based on a cubic spline (file c_spline.zmx). All points are in ascending order but oscillation appears. Note that Bezier curves described above are free from oscillations. A cubic spline can be easily modeled in most CAD software.

Some surfaces can’t be represented in implicit form, but they can be parametric where each surface point satisfies the equations [3]: xS = f(u,v), yS = g(u,v), zS = h(u,v), where (u,v) - parameters of surface. The normal vector to surface at point xS0 = f(u0,v0), yS0 = g(u0,v0), zS0 = h(u0,v0) is defined by the crossproduct:![]()
Ray equations are xR = x1 + lt, yR = y1 + mt, zR = z1 + nt. Here, (x,y,z) are ray coordinates at flat triangular facet, (l,m,n) are ray direction cosines. At ray-surface intersection point, we must have xR = xS, yR = yS, zR = zS. So we obtained system of equations Fx = f(u,v) - (x + lt) = 0, Fy = g(u,v) - (y + mt) = 0, Fz = h(u,v) - (z + nt) = 0 and three unknown parameters (t,u,v). If solved, distance to actual surface and normal vector is obtained.
As an example, let’s choose a surface of revolution of Bezier curve as a side surface; front and rear are still flat. A Bezier curve is parametric and defined by the following equations [4]: ![]()
where:![]()
Here, Pi = (Xi,Yi) are control points of Bezier curve and the total number of points is n+1. With a two dimensional curve, B(t) = (Bx(t),Bz(t)). For revolution of a curve, the parameter v must be included, so the surface of revolution is xS = By(u) sin(v), yS = By(u) cos(v), zS = Bx(u). Note that these three equations are correct for other curves. The surfaces of revolution of Bezier and native curves are shown below.
To solve the above system of equations, the Newton method described in [5] is used: F(X) = (Fx(X),Fy(X),Fz(X)) = 0, where X = (u,v,t). Then next iteration root is Xk+1 = Xk - J(Xk)-1F(Xk), where -1 power denotes inverse matrix and J denotes Jacobian of F:
When ||Xk - Xk+1|| < e, where e is a user-defined small number, the system is solved. With a periodic function, the result can be incorrect and the choice of starting point for the Newton method is very important.
A user-defined DLLs sample for cubic spline and Bezier-based object can be found in the ZIP archive on the last page of this article. Filenames are bezier_r.dll, c_spline_r.dll. The C code is included in files bezier_r.c, c_spline_r.c. Note that both DLLs are compiled for the SSE2 processor instruction set (modern processors). With old processors, C files can be compiled and DLL needs to be built for the usable processor. Parameters 1 and 2 specify the facets numbers, while parameters from 3 to 22 specify data points.
The ZEMAX Bezier object is created as shown below. It has 10 radial and 10 angular facets. Raytraces are set up with source ellipse. Note how rays refract on the object: they cross exact surface geometry instead of at facets.
If the number of facets is increased, the picture is improved.
User-defined objects can be exported from ZEMAX to CAD formats (SAT, STEP or IGES). Note that the resulting file is not of a smooth surface, but rather a set of flat facets. To obtain the exact solid geometry, an external CAD software can be used such as Rhino3D, KOMPAS, AutoCAD, or ProEngineer. The Bezier curve points can then be set manually and the CAD file rotated and exported or saved for future work.
The file bezier_r.sat is created in CAD software. Raytrace is then run for the DLL object and the imported object with 1 million rays (test.zmx and testCAD.zmx files). Note to check memory usage. The analysis was done with a Core2Duo T5500 processor and the 6/24/08 ZEMAX version. Results are shown in the table below.
| Bezier DLL | Imported | |
| Memory Usage, MB | 102 | 225 |
| Raytrace time, min | 2.075 | 25.57 |
