68 lines
2.5 KiB
C#
68 lines
2.5 KiB
C#
|
namespace LensSimulatorCore.Optical;
|
||
|
|
||
|
public class Material
|
||
|
{
|
||
|
public SellmeierCoefficients Sellmeier { get; set; }
|
||
|
|
||
|
public double RefractiveIndex(double wavelength)
|
||
|
{
|
||
|
return Sellmeier.CalculateRefractiveIndex(wavelength);
|
||
|
}
|
||
|
|
||
|
private readonly Func<double, double, double, double> _reflectivity;
|
||
|
private readonly Func<double, double, double, double> _transmissivity;
|
||
|
|
||
|
public Material(SellmeierCoefficients sellmeierCoefficients)
|
||
|
{
|
||
|
Sellmeier = sellmeierCoefficients;
|
||
|
_reflectivity = ComputeReflectivity;
|
||
|
_transmissivity = (angle, n1, wavelength) => 1.0 - Reflectivity(angle, n1, wavelength);
|
||
|
}
|
||
|
|
||
|
private double ComputeReflectivity(double angleDegrees, double n1, double wavelength)
|
||
|
{
|
||
|
// Convert angle to radians
|
||
|
var angleRadians = angleDegrees * Math.PI / 180.0;
|
||
|
|
||
|
// Check for total internal reflection
|
||
|
var criticalAngle = Math.Asin(RefractiveIndex(wavelength) / n1);
|
||
|
if (angleRadians > criticalAngle)
|
||
|
{
|
||
|
return 1.0;
|
||
|
}
|
||
|
|
||
|
var rs = ComputeFresnelCoefficient(angleRadians, n1, wavelength, isSPolarized: true);
|
||
|
var rp = ComputeFresnelCoefficient(angleRadians, n1, wavelength, isSPolarized: false);
|
||
|
return (rs + rp) / 2.0;
|
||
|
}
|
||
|
|
||
|
private double ComputeFresnelCoefficient(double angle, double n1, double wavelength, bool isSPolarized)
|
||
|
{
|
||
|
double numerator;
|
||
|
double denominator;
|
||
|
|
||
|
if (isSPolarized)
|
||
|
{
|
||
|
numerator = n1 * Math.Cos(angle) - RefractiveIndex(wavelength) * Math.Sqrt(1 - Math.Pow((n1 / RefractiveIndex(wavelength) * Math.Sin(angle)), 2));
|
||
|
denominator = n1 * Math.Cos(angle) + RefractiveIndex(wavelength) * Math.Sqrt(1 - Math.Pow((n1 / RefractiveIndex(wavelength) * Math.Sin(angle)), 2));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
numerator = n1 * Math.Sqrt(1 - Math.Pow((n1 / RefractiveIndex(wavelength) * Math.Sin(angle)), 2)) - RefractiveIndex(wavelength) * Math.Cos(angle);
|
||
|
denominator = n1 * Math.Sqrt(1 - Math.Pow((n1 / RefractiveIndex(wavelength) * Math.Sin(angle)), 2)) + RefractiveIndex(wavelength) * Math.Cos(angle);
|
||
|
}
|
||
|
|
||
|
return Math.Pow(numerator / denominator, 2);
|
||
|
}
|
||
|
|
||
|
// ReSharper disable once MemberCanBePrivate.Global
|
||
|
public double Reflectivity(double angle, double n1, double wavelength)
|
||
|
{
|
||
|
return _reflectivity(angle, n1, wavelength);
|
||
|
}
|
||
|
|
||
|
public double Transmissivity(double angle, double n1, double wavelength)
|
||
|
{
|
||
|
return _transmissivity(angle, n1, wavelength);
|
||
|
}
|
||
|
}
|