Модель линзы
Опишем модель линзы, зададим свойства оптической системы и оценим, как через нее проходят параллельные лучи.
Описание задачи
Мы создадим модель линзы и поверхности. Свет будет распространяться через воздух (индекс рефракции которого равен 1.0), потом пересечет сферическую поверхность, оптический центр которой расположен в точке 1 (у координат нет размерности, пользователь может выражать их в любой системе). Радиус первой сферической поверхности равен 6.0. Затем свет проходит через материал с индексом рефракции 1.5 (стекло) до достижения второй сферической поверхности, расположенной на оси Z по координате 2 и имеющей радиус -6. После пересечения второй поверхности луч снова проходит через воздух и достигает поверхности, расположенной на оси Z в точке с координатой 8.
Для этой работы мы воспользуемся пакетом для расчетов задач геометрической оптики GeometricalOptics.
Pkg.add( url="https://github.com/airspaced-nk5/GeometricalOptics.jl#master" )
Геометрия линзы и стены, ограничивающей распространение лучей, определяется следующим образом:
using GeometricalOptics
funcsList = [spherical, spherical, zplane] # объекты на пути луча
coeffsList = [[1., 6.], [2., -6.], [8.]] # свойства объектов
nList = [1., 1.5, 1.] # индексы рефракции
optSta = opticalstack( coeffsList, funcsList, nList );
Мы видим, что в системе три объекта: две сферические поверхности spherical (на которых происходит преломление) и одна плоскость zplane.
Коэффициенты рефракции указаны для сред, через которые свет проходит до пересечения очередной границы (заданной соответствующим объектом в списке
funcsList). В нашем случае первый коэффициент характеризует пространство перед линзой.
Объект spherical в библиотеке определён функцией spherical( x, y, coeffs=[zpos,signed_radius] ), где zpos – положение объекта на оптической оси, а signed_radius – радиус кривизны поверхности.
Пользователь может создавать собственные функции и задействовать их в определении оптической системы. Например, функция
my_ytilt(x,y,coeffs)=coeffs[1]+coeffs[2]*yсоздаст описание наклонной плоскости, положение которой на оси Z определяется первым из коэффициентов, а наклон по оси Y – вторым.
Создаем источник лучей
Самый лаконичный способ создания пучка из параллельно направленных лучей – функция bundle(x,y,angx,angy,zpos). Другие функции тоже присутствуют, например bundle_as_array, которая позволяет создать пучок с круглым сечением.
Функция bundle принимает аргументы x,y,zpos (положение центра пучка) и angx,angy (расхождение лучей в пучке, заданное в радианах, по осям X и Y). Каждый аргумент может быть задан вектором, поэтому следующая команда создает гребенку из лучей.
test_bundle = bundle( [0.], (-1:0.2:1), 0., 0., 0. );
Каждый луч начинается в точке с координатами X=0 и Z=0, а всего мы создаем 11 лучей с координатами от -1 до 1 с интервалом 0.2.
Расчет и вывод графиков
Для этой системы можно построить несколько разных графических диаграмм.
Характеристика искривления пучка
У нас имеется 1 источник и k поверхностей, значит можно соотнести зависимость координат лучей в пучке между любыми двумя поверхностями из k+1 имеющихся.
Если просто передать пучок test_bundle в объект optSta ("оптический стэк") и вывести график при помощи функции rac, то мы получим одну кривую.
trace1 = optSta( test_bundle )
rac( trace1, 1, 4 )
Перед нами график зависимости координат каждого луча в пучке на четвертой поверхности (ось Y) от его координаты на первой поверхности (ось X).
Команда rms_spot вернет среднеквадратическое рассеивание пучка на последней поверхности оптической системы (если вызвать ее без дополнительных аргументов).
rms = rms_spot( trace1 )
Двухмерный график распространения лучей
Если передать объекту optSta не только характеристику источника test_bundle, но и аргумент rend, то на выводе мы получим двухмерный (или трехмерный) график.
p_lens = optSta( test_bundle; rend = "YZ" )
Поэкспериментируйте с возможными аргументами этой команды чтобы получить разные графики (мы перевели график в формат gr() ради ускорения отрисовки).
gr()
rend = "3Dcirc" # @param ["YZ", "XZ", "3Dcirc", "3Dsq"]
ymin = -2.0
ymax = 2.0
p_lens = optSta(test_bundle; rend=rend, ydom = -2:0.1:2)
Заключение
Мы научились пользоваться библиотекой GeometricalOptics для описания простых моделей, демонстрирующих эффекты геометрической оптики (модель не отражает волновые эффекты).
Помимо установки библиотеки, нам потребовалось 7 строчек кода чтобы создать модель распространения пучка лучей через линзу.