15 лет назад я пытался писать диссертацию на тему «Оптоэлектронный метод определения шероховатости поверхности». В ходе работы активно использовались BRDF-функции и прочий замечательный математический аппарат для оптики. Был написан код и пара глав, но интерес пропал — повяз в работе. Пару раз пытался заново начать, но, к сожалению, так и не нашел причины выключиться из семьи и работы на год или даже больше. В качестве побочной задачки решил для себя реализовать визуализацию какого-нибудь интересного оптического эффекта. Выбор пал на интерференцию (wiki: взаимное увеличение или уменьшение результирующей амплитуды двух или нескольких когерентных волн при их наложении друг на друга), как наиболее простую в реализации механику.
Первая версия была реализована на Delphi + OpenGL ещё в 2005 году, она предполагала манимацию смены фазы волны и состояла всего из 200 строк кода. Удивительно, но ее код до сих пор доступен в Кладовке.
«Физика» отрисовки проста:
В JSFiddle доступен исходный код и есть возможность поиграться, устанавливая источники в различные углы сцены.
Первая версия была реализована на Delphi + OpenGL ещё в 2005 году, она предполагала манимацию смены фазы волны и состояла всего из 200 строк кода. Удивительно, но ее код до сих пор доступен в Кладовке.
Вернемся к более поздней версии, выполненной уже на JavaScript.
«Физика» отрисовки проста:
- Помещаем на страницу canvas и навешиваем событие onclick, которое запоминает координаты двух последних кликов мыши — источников излучения: (x1, y1) и (x2, y2).
- Проходим в цикле по каждой точке canvas (x, y) и вычисляем евклидово расстояние до наших источников излучения: S1=SQRT((x1-x)^2+(y1-y)^2) и S2=SQRT((x2-x)^2+(y2-y)^2)
- Мы предполагаем, что наши источники излучают синусоидальный сигнал, поэтому можем легко вычислить амплитуду каждой точки: A(x, y)=sin(S1 * W)+sin(S2 * W), где W — длина волны. Сюда можно еще добавить фазу, но это по желанию.
- Далее нормируем полученную амплитуду и получаем цвет пикселя: C(x,y)=A(x,y)*68+127
- ???
- Profit
В JSFiddle доступен исходный код и есть возможность поиграться, устанавливая источники в различные углы сцены.
Если вам интересно можете добавить «реалистичности»
- Затухание сигнала.
- Анимацию изменения фазы.
- Отражение сигнала от плоскости (через аффинные преобразования легче всего).