В этом руководстве вы познакомитесь с основами создания собственного модуля, который можно реализовать полностью в веб-приложении, без необходимости использования какой-либо внешней среды разработки.
Функция "Модуль" Ray Optics Simulation позволяет создавать модульные комбинации объектов с польз. параметрами, польз. контрольными точками и массивами объектов. Эта функция расширяет возможности симулятора, комбинируя, специализируя или изменяя параметры, объекты, созданные существующими инструментами, для создания новых инструментов. Например, модуль CircleSource
(см. Инструменты -> Другое -> Модуль Импорт) объединяет массив точечных источников, созданных существующим инструментом "Точечный источник (<360°)", вдоль окружности, чтобы создать инструмент "круговой источник", которого не было в симуляторе. Модуль FresnelLens
специализирует инструмент "Стекло->Польз. уравнение" таким образом, что уравнение представляет собой определенную кривую линзы Френеля, параметризованную кол-вом срезов, таким образом, создавая специализированный инструмент "линза Френеля", которого также не существовало ранее. Помимо создания новых инструментов, эта функция также может сделать некоторые демонстрации оптики более интерактивными. Например, перетащив третью контрольную точку модуля BeamExpander
, можно непосредственно увидеть, как положение общей фокусной точки 2-х линз влияет на ширину луча, без необходимости настраивать фокусные расстояния 2-х линз по отдельности.
Обратите внимание, что не для всех польз. точек управления требуется модуль. Некоторые простые случаи можно решить с помощью функции "ручка" (см. раздел "Группировка, поворот и масштабирование объектов" во всплывающем окне справки в правом нижнем углу симулятора). Поскольку создание модуля намного сложнее, чем создание ручки, перед тем как приступить к созданию модуля, следует проверить, можно ли решить вашу задачу с помощью функции "ручка". Смотрите здесь необычный пример польз. контрольной точки (перемещение 2-х пластиковых пакетов из воды) без использования модуля.
С другой стороны, если ваш случай требует сложного программирования (например, создания анимации, использ. сложного алгоритма размещения оптических элементов или анализа карт освещенности), пожалуйста, использ. инструменты интеграции и пишите скрипты, например, на Python или Julia.
Вы можете вносить свои модули в список "Импортные модули", если считаете, что они полезны для других, даже если они vibe-кодированы!
Ray Optics Coder на ChatGPT может помочь вам в написании модулей Ray Optics. Он генерирует JSON-код для сцены, содержащей модуль, на основе вашего описания, а затем вы можете скопировать этот код в JSON-редактор (см. ниже). Вы также можете использовать его для редакт. существующих модулей или для модульного построения сцен.
Код, сгенерированный ИИ, может не работать напрямую. Если возникла ошибка, вам может помочь копирование и вставка сообщения об ошибке в ИИ. Для более сложных модулей вам, возможно, стоит прочитать учебник ниже и хотя бы частично написать код самостоятельно.
Файлы с инструкциями и знаниями для ИИ доступны здесь. Если вы предпочитаете другой LLM-сервис, вы можете предоставить эти файлы, чтобы научить его писать модули Ray Optics.
В настоящее время в этом приложении нет визуального интерфейса для создания модулей, поэтому вам нужно напрямую редактировать JSON сцены.
Вы можете вкл. встроенный редактор JSON, нажав на выпадающий список "настройки" в правом верхнем углу приложения, а затем установив флажок "Показывать редактор JSON". В левой части приложения должен появиться редактор кода с JSON-кодом текущей сцены. Убедитесь, что у вас достаточно большой экран, так как эта функция не очень хорошо работает на мобильных устройствах.
При редакт. сцены с помощью обычного визуального редактора сцен код в редакторе JSON будет обновляться соответствующим образом, а измененная часть будет выделена. И наоборот, при непосредственном редакт. кода в редакторе JSON сцена будет обновляться соответствующим образом. Если вы не знакомы с JSON или любым другим текстовым форматом данных, вам, возможно, захочется немного поиграть с ним.
В частности, когда вы добавляете объект на сцену, он добавляется в массив objs
. И если вы изменяете некоторые его свойства на значения, не соответствующие по умолчанию, они появляются как пары ключ-значение в этом объекте.
ВАЖНО: Если на этой странице вы не видите редактор JSON-кода в iframe, пожалуйста, включите его и перезагрузите эту страницу, т.к. вам нужно увидеть код, чтобы понять, как он работает.
Давайте' рассмотрим наш первый пример модуля.
Вы должны увидеть 4 строки текста. Посмотрев в редактор JSON, вы увидите, что первые две находятся непосредственно в массиве верхнего уровня objs
, как обычно, а последние две - в modules.ExampleModule.objs
.
Массив modules
представляет собой словарь, в котором ключом является название модуля (в данном случае ExampleModule
), а значением - определение этого модуля. В частности, массив modules.ExampleModule.objs
описывает (шаблон) объекты внутри этого модуля, что отличается от высш. уровня objs
, который описывает объекты в сцене.
Чтобы поместить объекты модуля на сцену, нам нужен "объект модуля" в массиве высш. уровня objs
, в данном примере это objs[2]
, тип которого ModuleObj
и свойство module
которого является именем модуля.
Определение модуля в словаре modules
не редакт. визуальным редактором сцены. Поэтому, когда вы щелкаете на любом из 2-х последних текстов в этом примере, вы просто выбираете объект модуля, а не объекты в модуле. Поскольку координаты текстов в определении модуля в этом примере являются абсолютными координатами, последние 2 текста не могут перетаскиваться. Позже мы узнаем, как сделать их перетаскиваемыми с помощью контрольных точек.
Если вы выделите объект модуля, на панели объектов появится кнопка "Демодулировать". Нажав ее, вы "развернете" объект модуля на его составные части, и objs
теперь будет содержать все 4 текста. Эта операция неизменяемая (но, конечно, вы можете нажать кнопку "Отменить").
В настоящее время предлагается создать пустой модуль с помощью редактора JSON, создать несколько объектов с помощью редактора визуальных сцен, а затем вырезать и вставить объекты из objs
в modules.ModuleName.objs
с помощью редактора JSON.
Объекты внутри модуля могут быть определены набором параметров. Давайте рассмотрим простой пример
Здесь modules.ModuleName.params
- это массив строк "name=start:step:end:default"
, определяющих название переменных и диапазон ползунков. Ползунки появляются на панели объектов, когда выбран объект модуля.
В массиве modules.ExampleModule.objs
через эти параметры могут быть выражены любые значения. В строке (например, свойство text
для TextLabel
) уравнения переменных заключаются в пару обратных знаков. Для числовых параметров (например, свойства fontSize
в TextLabel
) необходимо сделать его строкой, чтобы в нем можно было использовать формат обратных знаков, поэтому каждое уравнение заключено в пару обратных знаков и пару кавычек. Уравнения оцениваются с помощью math.js (синтаксис). См. там, какой синтаксис и функции можно использ. в уравнениях.
Фактические значения параметров хранятся в свойстве params
объекта модуля, которое, в отличие от определения модуля, может быть непосредственно отредактировано редактором сцены с помощью ползунка.
Чтобы сделать объект модуля перетаскиваемым, нам нужно настроить параметры объекты внутри модуля с помощью набора контрольных точек. Давайте рассмотрим пример
Здесь modules.ModuleName.numPoints
задает кол-во контрольных точек. Координаты контрольных точек - (x_1
, y_1
), (x_2
, y_2
) и т.д., и используются так же, как и параметры в modules.ExampleModule.objs
, как описано в предыдущем разделе. Обратите внимание, что индекс начинается с 1.
Фактические значения координат контрольных точек хранятся в свойстве points
объекта модуля, которое, в отличие от жестко закодированных координат в примере 1, можно редакт. в визуальном редакторе сцены, перетаскивая контрольные точки, каждая из которых отображается в виде 2-х концентрических серых кругов на сцене. Если вы перетащите объект модуля в др. место (например, перетащите текстовые метки), все контрольные точки будут перемещаться вместе.
Поскольку наш объект модуля теперь может перемещаться, теперь довольно легко создать несколько экземпляров, как в обычных инструментах. Имя модуля отображается в меню Инструменты -> Другое, и вы можете выбрать его, а затем щелкнуть 2-е точки в пустом пространстве последовательно для двух контрольных точек, чтобы создать еще один экземпляр модуля. Также можно использ. кнопку "Дублировать" на панели объектов.
Более сложный модуль можно построить с помощью массивов и условий. Давайте рассмотрим пример
В рамках modules.ExampleModule.objs
любые объекты в массиве могут иметь два специальных ключа: "for"
и "if"
. Значение ключа "for"
- это либо строка формата "name=start:step:end"
, определяющая переменную цикла, либо массив из нескольких строк такого формата, описывающий многомерный цикл. Такой объект в массиве дублируется несколько раз в соответствии с переменными цикла. Значение ключа "if"
- это строка, представляющая выражение math.js, которое оценивается как логический, и такой объект включается в массив тогда и только тогда, когда это логическое истинно.
Чтобы предотвратить случайный бесконечный цикл, общее кол-во итераций каждого цикла "for"
ограничено свойством maxLoopLength
в определении модуля, значение которого по умолчанию равно 1000. При необходимости вы можете установить это свойство на большее значение.
Вы можете определить математические переменные и функции, которые будут использ. во всем модуле. Давайте рассмотрим пример
Массив modules.ModuleName.vars
- это массив строк, каждая из которых представляет собой оператор math.js, определяющий переменную или функцию. Эти определения оцениваются последовательно, поэтому более поздние определения могут ссылаться на более ранние.
Определения переменных имеют полный доступ ко всем параметрам и координатам контрольных точек, а после определения эти переменные могут использоваться в шаблонах объектов так же, как параметры и координаты контрольных точек, что позволяет выполнять более сложные и многократно используемые вычисления.
Для объектов, в которых уже есть ввод польз. уравнений (например, Зеркало -> Пользовательское уравнение), свойство уравнения в JSON представляет собой строку, представляющую уравнение LaTeX, а не выражение math.js. Чтобы включить польз. параметры в уравнение, вы должны использовать тот же синтаксис шаблона, как если бы уравнение LaTeX было обычным текстом. Таким образом, часть, заключенная в обратные знаки, будет выражением math.js, а часть вне его - LaTeX. Доступ к параметрам модуля возможен только в части math.js, а к независимым переменным польз. уравнения (например, \(x\)) - только в части LaTeX. Вот пример генерации зеркала с уравнением \(y=\cos(2\pi x+\phi)\), где \(\phi\) - параметр модуля
В будущем, возможно, появится способ объединить в единое целое ввод уравнения.
Для объектов, которые уже поддерживают различные способы определения своей формы (в настоящее время только Стекло -> Сферическая линза). Для таких объектов существует специальный JSON-синтаксис, который можно использовать в определении модуля, даже если они всегда определяются по форме в массиве верхнего уровня objs
. Вот пример