From c43507c33f3d199504a9d2f2dae017027fc6389d Mon Sep 17 00:00:00 2001 From: Yi-Ting Tu Date: Thu, 25 Jul 2024 23:26:59 -0400 Subject: [PATCH] Add chromatic dispersion support in GRIN glass --- simulator/js/ObjBar.js | 2 +- simulator/js/objs/BaseGrinGlass.js | 10 +++++----- simulator/locales/de.js | 2 +- simulator/locales/en.js | 2 +- simulator/locales/es.js | 2 +- simulator/locales/fr.js | 2 +- simulator/locales/ja.js | 2 +- simulator/locales/ko.js | 2 +- simulator/locales/nl.js | 2 +- simulator/locales/pl.js | 2 +- simulator/locales/pt_BR.js | 2 +- simulator/locales/ru.js | 2 +- simulator/locales/si.js | 2 +- simulator/locales/template.js | 2 +- simulator/locales/zh_CN.js | 2 +- simulator/locales/zh_TW.js | 2 +- 16 files changed, 20 insertions(+), 20 deletions(-) diff --git a/simulator/js/ObjBar.js b/simulator/js/ObjBar.js index bca81365..785ecaee 100644 --- a/simulator/js/ObjBar.js +++ b/simulator/js/ObjBar.js @@ -312,7 +312,7 @@ class ObjBar { supSubsRequireOperand: true, charsThatBreakOutOfSupSub: '+-=<>', autoSubscriptNumerals: true, - autoCommands: 'pi theta sqrt sum', + autoCommands: 'pi theta lambda sqrt sum', autoOperatorNames: 'sin cos tan sec csc cot sinh cosh tanh log exp arcsin arccos arctan asin acos atan arcsinh arccosh arctanh asinh acosh atanh floor round ceil trunc sign sgn max min abs', maxDepth: 10, handlers: { diff --git a/simulator/js/objs/BaseGrinGlass.js b/simulator/js/objs/BaseGrinGlass.js index 91d2b106..8fa33929 100644 --- a/simulator/js/objs/BaseGrinGlass.js +++ b/simulator/js/objs/BaseGrinGlass.js @@ -79,7 +79,7 @@ class BaseGrinGlass extends BaseGlass { } getRefIndexAt(point, ray) { - return this.fn_p({ x: point.x, y: point.y }); + return this.fn_p({ x: point.x, y: point.y, z: ray.wavelength || GREEN_WAVELENGTH }); } onRayEnter(ray) { @@ -105,12 +105,12 @@ class BaseGrinGlass extends BaseGlass { initFns() { this.error = null; try { - this.p = parseTex(this.refIndexFn).toString().replaceAll("\\cdot", "*").replaceAll("\\frac", "/"); + this.p = parseTex(this.refIndexFn.replaceAll("\\lambda", "z")).toString().replaceAll("\\cdot", "*").replaceAll("\\frac", "/"); this.p_der_x = math.derivative(this.p, 'x').toString(); this.p_der_x_tex = math.parse(this.p_der_x).toTex().replaceAll("{+", "{"); // 'evaluateLatex' function can't and can handle expressions of the form '...num^{+exp}...' and '...num^{exp}...', respectively, where num and exp are numbers this.p_der_y = math.derivative(this.p, 'y').toString(); this.p_der_y_tex = math.parse(this.p_der_y).toTex().replaceAll("{+", "{"); - this.fn_p = evaluateLatex(this.shiftOrigin(this.refIndexFn)); + this.fn_p = evaluateLatex(this.shiftOrigin(this.refIndexFn.replaceAll("\\lambda", "z"))); this.fn_p_der_x = evaluateLatex(this.shiftOrigin(this.p_der_x_tex)); this.fn_p_der_y = evaluateLatex(this.shiftOrigin(this.p_der_y_tex)); } catch (e) { @@ -262,8 +262,8 @@ class BaseGrinGlass extends BaseGlass { const x_der_s_prev = (p2.x - p1.x) / len; const y_der_s_prev = Math.sign(p2.y - p1.y) * Math.sqrt(1 - x_der_s_prev ** 2); - const x_der_s = x_der_s_prev + this.stepSize * (ray.bodyMergingObj.fn_p_der_x({ x: x, y: y }) * (1 - x_der_s_prev ** 2) - ray.bodyMergingObj.fn_p_der_y({ x: x, y: y }) * x_der_s_prev * y_der_s_prev) / ray.bodyMergingObj.fn_p({ x: x, y: y }); - const y_der_s = y_der_s_prev + this.stepSize * (ray.bodyMergingObj.fn_p_der_y({ x: x, y: y }) * (1 - y_der_s_prev ** 2) - ray.bodyMergingObj.fn_p_der_x({ x: x, y: y }) * x_der_s_prev * y_der_s_prev) / ray.bodyMergingObj.fn_p({ x: x, y: y }); + const x_der_s = x_der_s_prev + this.stepSize * (ray.bodyMergingObj.fn_p_der_x({ x: x, y: y, z: ray.wavelength || GREEN_WAVELENGTH }) * (1 - x_der_s_prev ** 2) - ray.bodyMergingObj.fn_p_der_y({ x: x, y: y, z: ray.wavelength || GREEN_WAVELENGTH }) * x_der_s_prev * y_der_s_prev) / ray.bodyMergingObj.fn_p({ x: x, y: y, z: ray.wavelength || GREEN_WAVELENGTH }); + const y_der_s = y_der_s_prev + this.stepSize * (ray.bodyMergingObj.fn_p_der_y({ x: x, y: y, z: ray.wavelength || GREEN_WAVELENGTH }) * (1 - y_der_s_prev ** 2) - ray.bodyMergingObj.fn_p_der_x({ x: x, y: y, z: ray.wavelength || GREEN_WAVELENGTH }) * x_der_s_prev * y_der_s_prev) / ray.bodyMergingObj.fn_p({ x: x, y: y, z: ray.wavelength || GREEN_WAVELENGTH }); const x_new = x + this.stepSize * x_der_s; const y_new = y + this.stepSize * y_der_s; diff --git a/simulator/locales/de.js b/simulator/locales/de.js index 65e19158..22ab03fa 100644 --- a/simulator/locales/de.js +++ b/simulator/locales/de.js @@ -441,7 +441,7 @@ locales["de"] = { }, "grin_refractive_index": { "incomplete": true, - "message": "" + "message": "" }, "symbolic_grin_note_popover": { "incomplete": true, diff --git a/simulator/locales/en.js b/simulator/locales/en.js index 0eece80c..9a5e20cc 100644 --- a/simulator/locales/en.js +++ b/simulator/locales/en.js @@ -406,7 +406,7 @@ locales["en"] = { "message": "Symbolic body-merging" }, "grin_refractive_index": { - "message": "" + "message": "" }, "symbolic_grin_note_popover": { "message": "

This toggle applies to all GRIN objects in the simulation.

This simulator has currently two implementations of light propagation between different mediums, for GRIN objects - numerical and symbolic (see 'multRefIndex' and 'devRefIndex' functions in 'CircleGrinGlass.js').

The numerical implementation is faster but doesn't always work properly (depending on the specific case) in scenarios when used with more than one GRIN object, such that at least one of them has a refractive index function which is not defined in the entire plane, while the symbolic implementation is slower but robust to such problems.

" diff --git a/simulator/locales/es.js b/simulator/locales/es.js index 30ce1530..5d24eaeb 100644 --- a/simulator/locales/es.js +++ b/simulator/locales/es.js @@ -422,7 +422,7 @@ locales["es"] = { }, "grin_refractive_index": { "incomplete": true, - "message": "" + "message": "" }, "symbolic_grin_note_popover": { "message": "

Esta opción se aplica a todos los objetos GRIN de la simulación.

Actualmente este simulador tiene dos implementaciones de propagación de la luz entre medios, para objetos GRIN - numéricos y simbólicos (vea las funciones 'multRefIndex' y 'devRefIndex' en 'CircleGrinGlass.js').

La implementación numérica es más rápida pero no siempre funciona correctamente (dependiendo del caso en concreto) en escenarios donde se usa más de un objeto GRIN,tal que al menos una de ellas tiene una función de índice de refracción que no está definida en todo el plano, mientras que la implementación simbólica és más lenta pero robusta con estos problemas.

" diff --git a/simulator/locales/fr.js b/simulator/locales/fr.js index 6c2e877b..b62e766a 100644 --- a/simulator/locales/fr.js +++ b/simulator/locales/fr.js @@ -466,7 +466,7 @@ locales["fr"] = { }, "grin_refractive_index": { "incomplete": true, - "message": "" + "message": "" }, "symbolic_grin_note_popover": { "incomplete": true, diff --git a/simulator/locales/ja.js b/simulator/locales/ja.js index 7e9f2d97..b49bc9b1 100644 --- a/simulator/locales/ja.js +++ b/simulator/locales/ja.js @@ -541,7 +541,7 @@ locales["ja"] = { }, "grin_refractive_index": { "incomplete": true, - "message": "" + "message": "" }, "symbolic_grin_note_popover": { "incomplete": true, diff --git a/simulator/locales/ko.js b/simulator/locales/ko.js index 892bb9d5..961973c6 100644 --- a/simulator/locales/ko.js +++ b/simulator/locales/ko.js @@ -541,7 +541,7 @@ locales["ko"] = { }, "grin_refractive_index": { "incomplete": true, - "message": "" + "message": "" }, "symbolic_grin_note_popover": { "incomplete": true, diff --git a/simulator/locales/nl.js b/simulator/locales/nl.js index 7f7c48f0..729e75b2 100644 --- a/simulator/locales/nl.js +++ b/simulator/locales/nl.js @@ -481,7 +481,7 @@ locales["nl"] = { }, "grin_refractive_index": { "incomplete": true, - "message": "" + "message": "" }, "symbolic_grin_note_popover": { "incomplete": true, diff --git a/simulator/locales/pl.js b/simulator/locales/pl.js index d1226a0e..17089004 100644 --- a/simulator/locales/pl.js +++ b/simulator/locales/pl.js @@ -425,7 +425,7 @@ locales["pl"] = { }, "grin_refractive_index": { "incomplete": true, - "message": "" + "message": "" }, "symbolic_grin_note_popover": { "message": "

Ten przełącznik dotyczy wszystkich obiektów GRIN w symulacji.

Ten symulator ma obecnie dwie implementacje propagacji światła między różnymi ośrodkami dla obiektów GRIN - numeryczną i symboliczną (patrz funkcje 'multRefIndex' i 'devRefIndex' w 'CircleGrinGlass.js').

Implementacja numeryczna jest szybsza, ale nie zawsze działa poprawnie (w zależności od konkretnego przypadku) w scenariuszach, gdy jest używana z więcej niż jednym obiektem GRIN, takim, że przynajmniej jeden z nich ma funkcję współczynnika załamania światła, która nie jest zdefiniowana w całej płaszczyźnie, podczas gdy implementacja symboliczna jest wolniejsza, ale odporna na takie problemy.

" diff --git a/simulator/locales/pt_BR.js b/simulator/locales/pt_BR.js index 60a21010..78a2d239 100644 --- a/simulator/locales/pt_BR.js +++ b/simulator/locales/pt_BR.js @@ -415,7 +415,7 @@ locales["pt-BR"] = { "message": "União simbólica de corpos" }, "grin_refractive_index": { - "message": "" + "message": "" }, "symbolic_grin_note_popover": { "message": "

Esta opção se aplica a todos objetos GRIN na simulação.

Este simulador atualmente possi duas implementações de propagação de luz entre meios diferentes, para objetos GRIN - numérica e simbólica (ver funções 'multRefIndex' e 'devRefIndex' em 'CircleGrinGlass.js').

A implementação numérica é mais rápida mas nem sempre funciona corretamente (dependende do caso específico) em cenários quando é usada com mais de um objeto GRIN, tal que ao menos um deles possua uma função de índice refrativo que não é definida todo o plano, enquanto a implementação simbólica é mais lenta, mas robusta a esse tipo de problema.

" diff --git a/simulator/locales/ru.js b/simulator/locales/ru.js index 506c900f..4a6fa4e1 100644 --- a/simulator/locales/ru.js +++ b/simulator/locales/ru.js @@ -468,7 +468,7 @@ locales["ru"] = { }, "grin_refractive_index": { "incomplete": true, - "message": "" + "message": "" }, "symbolic_grin_note_popover": { "incomplete": true, diff --git a/simulator/locales/si.js b/simulator/locales/si.js index a5a812c8..89bc3c63 100644 --- a/simulator/locales/si.js +++ b/simulator/locales/si.js @@ -428,7 +428,7 @@ locales["si"] = { }, "grin_refractive_index": { "incomplete": true, - "message": "" + "message": "" }, "symbolic_grin_note_popover": { "incomplete": true, diff --git a/simulator/locales/template.js b/simulator/locales/template.js index cf05bf1d..b95ee577 100644 --- a/simulator/locales/template.js +++ b/simulator/locales/template.js @@ -541,7 +541,7 @@ locales["LOCALE_ID"] = { }, "grin_refractive_index": { "incomplete": true, - "message": "" + "message": "" }, "symbolic_grin_note_popover": { "incomplete": true, diff --git a/simulator/locales/zh_CN.js b/simulator/locales/zh_CN.js index 078cc860..731739c4 100644 --- a/simulator/locales/zh_CN.js +++ b/simulator/locales/zh_CN.js @@ -406,7 +406,7 @@ locales["zh-CN"] = { "message": "符号式物体融合" }, "grin_refractive_index": { - "message": "" + "message": "" }, "symbolic_grin_note_popover": { "message": "

本选项会套用至所有渐变折射率透光物。

本模拟器目前有两种光线经过不同渐变折射率介质的实作 - 数值与符号(见 'CircleGrinGlass.js' 中的 'multRefIndex' 与 'devRefIndex' 函数)。

数值的实作较快,但使用多个渐变折射率介质,且至少有一个介质的折射率没有在整个平面上有定义时,无法在所有情况下正常运作(取决于具体情况)。相较之下,符号的实作较慢但在这种情况下仍可正常运作。

" diff --git a/simulator/locales/zh_TW.js b/simulator/locales/zh_TW.js index ec524428..a6fc5d0e 100644 --- a/simulator/locales/zh_TW.js +++ b/simulator/locales/zh_TW.js @@ -406,7 +406,7 @@ locales["zh-TW"] = { "message": "符號式物體融合" }, "grin_refractive_index": { - "message": "" + "message": "" }, "symbolic_grin_note_popover": { "message": "

本選項會套用至所有漸變折射率透光物。

本模擬器目前有兩種光線經過不同漸變折射率介質的實作 - 數值與符號(見 'CircleGrinGlass.js' 中的 'multRefIndex' 與 'devRefIndex' 函數)。

數值的實作較快,但使用多個漸變折射率介質,且至少有一個介質的折射率沒有在整個平面上有定義時,無法在所有情況下正常運作(取決於具體情況)。相較之下,符號的實作較慢但在這種情況下仍可正常運作。

"