MultiFocusParameters.java
package org.fresnel.optics;
import java.util.List;
/**
* Parameters for a multi-point / line focus zone plate. The aperture is divided
* into N sub-apertures (one per focus target) by a deterministic per-pixel hash;
* each sub-aperture diffracts toward its own (xf, yf, zf). This produces N distinct
* focal spots; for line focus, supply many targets along a line.
*
* @param apertureDiameterMm aperture diameter, mm
* @param focusPoints list of focus targets {@code (x, y, z)} in mm relative
* to the centre of the aperture (z is the focal distance)
* @param wavelengthNm wavelength, nm
* @param dpi printer DPI
* @param maskType binary amplitude or greyscale phase
* @param polarity polarity
*/
public record MultiFocusParameters(
double apertureDiameterMm,
List<FocusPoint> focusPoints,
double wavelengthNm,
double dpi,
MaskType maskType,
Polarity polarity
) {
/** A single (x, y, z) focus target in mm. */
public record FocusPoint(double xMm, double yMm, double zMm) {
public FocusPoint {
if (zMm <= 0) throw new IllegalArgumentException("zMm must be > 0");
}
}
public MultiFocusParameters {
if (apertureDiameterMm <= 0) throw new IllegalArgumentException("apertureDiameterMm must be > 0");
if (focusPoints == null || focusPoints.isEmpty())
throw new IllegalArgumentException("focusPoints must not be empty");
if (wavelengthNm <= 0) throw new IllegalArgumentException("wavelengthNm must be > 0");
if (dpi <= 0) throw new IllegalArgumentException("dpi must be > 0");
if (maskType == null) throw new IllegalArgumentException("maskType must not be null");
if (polarity == null) throw new IllegalArgumentException("polarity must not be null");
focusPoints = List.copyOf(focusPoints);
}
/** Build a line-focus design with {@code n} equally-spaced points between two endpoints. */
public static List<FocusPoint> lineOfPoints(
double x0, double y0, double z0,
double x1, double y1, double z1, int n) {
if (n < 2) throw new IllegalArgumentException("n must be ≥ 2");
List<FocusPoint> out = new java.util.ArrayList<>(n);
for (int i = 0; i < n; i++) {
double t = (double) i / (n - 1);
out.add(new FocusPoint(
x0 + t * (x1 - x0),
y0 + t * (y1 - y0),
z0 + t * (z1 - z0)));
}
return out;
}
}