<iframe src="http://jsxgraph.uni-bayreuth.de/share/iframe/snells-law" style="border: 1px solid black; overflow: hidden; width: 550px; aspect-ratio: 55 / 65;" name="JSXGraph example: Snell's law" allowfullscreen ></iframe>
<div id="board-0-wrapper" class="jxgbox-wrapper " style="width: 100%; "> <div id="board-0" class="jxgbox" style="aspect-ratio: 1 / 1; width: 100%;" data-ar="1 / 1"></div> </div> <script type = "text/javascript"> /* This example is licensed under a Creative Commons Attribution ShareAlike 4.0 International License. https://creativecommons.org/licenses/by-sa/4.0/ Please note you have to mention The Center of Mobile Learning with Digital Technology in the credits. */ const BOARDID = 'board-0'; var board = JXG.JSXGraph.initBoard(BOARDID, { boundingbox: [-5, 5, 5, -5], axis: false, keepaspectratio: true }); // Line l1 as an interface between two environments, green, with the index of refraction // n_1, and the blue, with the index of refraction n_2. var M = board.create('point', [-4, 0], { name: 'M', visible: false, fixed: true }); var I = board.create('point', [0, 0], { name: 'I', size: 1, fixed: true }); var l1 = board.create('line', [M, I]); var ineq1 = board.create('inequality', [l1], { fillColor: 'green' }); var ineq2 = board.create('inequality', [l1], { inverse: true, fillColor: 'blue' }); // Normal line n with auxiliary points N and O that allows us to determine // the angles of incidence (α) and refraction (β), respectively var n = board.create('perpendicular', [l1, I], { name: 'n', color: 'black', dash: "2", strokeWidth: 1 }); var N = board.create('glider', [0, 4, n], { name: 'N', visible: false }); var O = board.create('glider', [0, -4, n], { name: 'O', visible: false }); // a light source L var L = board.create('point', [-3, 4], { name: 'L', color: 'red', size: 3 }); // Position of the light source L is limited to the green environment var xL, yL; L.on('drag', function() { if (L.Y() < 0) { L.moveTo([xL, yL], 0); } xL = L.X(); yL = L.Y(); }); // r1, the incident light ray var r1 = board.create('segment', [L, I], { strokeColor: 'orange', strokeWidth: 4 }); // Sliders to control indexes of refraction var n_1 = board.create('slider', [[-4, -3], [-2, -3], [1, 1, 3]], { name: 'n_1', snapWidth: 0.01 }); var n_2 = board.create('slider', [[-4, -4], [-2, -4], [1, 1, 3]], { name: 'n_2', snapWidth: 0.01 }); // The value of s controls the kind of refraction/reflection, if s > 1 the total reflection occurs // (numerically it is the absolute value of the sine of the angle of refraction) var s = () => (n_1.Value() / n_2.Value()) * Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))).toFixed(6); // Two possible points through which the modified ray passes, B for the reflected ray and C for the refracted one var B = board.create('point', [ () => -L.X(), () => L.Y() ], { visible: () => (s() > 1 || Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) == 1) ? true : false, name: 'R_1', face: 'o', size: 1 }); var C = board.create('point', [ () => 5 * (n_1.Value() / n_2.Value()) * Math.sin(JXG.Math.Geometry.angle(N, I, L)), () => -5 * Math.cos(Math.asin((n_1.Value() / n_2.Value()) * Math.sin(JXG.Math.Geometry.angle(N, I, L)))) ], { visible: () => (s() <= 1 && Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) != 1) ? true : false, name: 'R_2', face: 'o', size: 1 }); // Reflected (r2) and refracted (r3) ray var r2 = board.create('segment', [I, B], { visible: () => (s() > 1 || Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) == 1) ? true : false, strokeColor: 'orange', strokeWidth: 4, lastArrow: { type: 1, size: 3 } }); var r3 = board.create('segment', [I, C], { visible: () => (s() <= 1 && Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) != 1) ? true : false, strokeColor: 'orange', strokeWidth: 4, lastArrow: { type: 1, size: 3 } }); // Angles of impact (angle 1), refraction (angle2) and reflection (angle3), respectively var angle1 = board.create('nonreflexangle', [N, I, L], { radius: 1, color: 'orange', fillOpacity: 0, name: 'α' }); var angle2 = board.create('nonreflexangle', [O, I, C], { visible: () => (s() <= 1 && Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) != 1) ? true : false, radius: 1, color: 'orange', fillOpacity: 0, name: 'β' }); var angle3 = board.create('nonreflexangle', [B, I, N], { visible: () => (s() > 1 || Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) == 1) ? true : false, radius: 1, color: 'orange', fillOpacity: 0, name: 'β' }); </script>
/* This example is licensed under a Creative Commons Attribution ShareAlike 4.0 International License. https://creativecommons.org/licenses/by-sa/4.0/ Please note you have to mention The Center of Mobile Learning with Digital Technology in the credits. */ const BOARDID = 'your_div_id'; // Insert your id here! var board = JXG.JSXGraph.initBoard(BOARDID, { boundingbox: [-5, 5, 5, -5], axis: false, keepaspectratio: true }); // Line l1 as an interface between two environments, green, with the index of refraction // n_1, and the blue, with the index of refraction n_2. var M = board.create('point', [-4, 0], { name: 'M', visible: false, fixed: true }); var I = board.create('point', [0, 0], { name: 'I', size: 1, fixed: true }); var l1 = board.create('line', [M, I]); var ineq1 = board.create('inequality', [l1], { fillColor: 'green' }); var ineq2 = board.create('inequality', [l1], { inverse: true, fillColor: 'blue' }); // Normal line n with auxiliary points N and O that allows us to determine // the angles of incidence (α) and refraction (β), respectively var n = board.create('perpendicular', [l1, I], { name: 'n', color: 'black', dash: "2", strokeWidth: 1 }); var N = board.create('glider', [0, 4, n], { name: 'N', visible: false }); var O = board.create('glider', [0, -4, n], { name: 'O', visible: false }); // a light source L var L = board.create('point', [-3, 4], { name: 'L', color: 'red', size: 3 }); // Position of the light source L is limited to the green environment var xL, yL; L.on('drag', function() { if (L.Y() < 0) { L.moveTo([xL, yL], 0); } xL = L.X(); yL = L.Y(); }); // r1, the incident light ray var r1 = board.create('segment', [L, I], { strokeColor: 'orange', strokeWidth: 4 }); // Sliders to control indexes of refraction var n_1 = board.create('slider', [[-4, -3], [-2, -3], [1, 1, 3]], { name: 'n_1', snapWidth: 0.01 }); var n_2 = board.create('slider', [[-4, -4], [-2, -4], [1, 1, 3]], { name: 'n_2', snapWidth: 0.01 }); // The value of s controls the kind of refraction/reflection, if s > 1 the total reflection occurs // (numerically it is the absolute value of the sine of the angle of refraction) var s = () => (n_1.Value() / n_2.Value()) * Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))).toFixed(6); // Two possible points through which the modified ray passes, B for the reflected ray and C for the refracted one var B = board.create('point', [ () => -L.X(), () => L.Y() ], { visible: () => (s() > 1 || Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) == 1) ? true : false, name: 'R_1', face: 'o', size: 1 }); var C = board.create('point', [ () => 5 * (n_1.Value() / n_2.Value()) * Math.sin(JXG.Math.Geometry.angle(N, I, L)), () => -5 * Math.cos(Math.asin((n_1.Value() / n_2.Value()) * Math.sin(JXG.Math.Geometry.angle(N, I, L)))) ], { visible: () => (s() <= 1 && Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) != 1) ? true : false, name: 'R_2', face: 'o', size: 1 }); // Reflected (r2) and refracted (r3) ray var r2 = board.create('segment', [I, B], { visible: () => (s() > 1 || Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) == 1) ? true : false, strokeColor: 'orange', strokeWidth: 4, lastArrow: { type: 1, size: 3 } }); var r3 = board.create('segment', [I, C], { visible: () => (s() <= 1 && Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) != 1) ? true : false, strokeColor: 'orange', strokeWidth: 4, lastArrow: { type: 1, size: 3 } }); // Angles of impact (angle 1), refraction (angle2) and reflection (angle3), respectively var angle1 = board.create('nonreflexangle', [N, I, L], { radius: 1, color: 'orange', fillOpacity: 0, name: 'α' }); var angle2 = board.create('nonreflexangle', [O, I, C], { visible: () => (s() <= 1 && Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) != 1) ? true : false, radius: 1, color: 'orange', fillOpacity: 0, name: 'β' }); var angle3 = board.create('nonreflexangle', [B, I, N], { visible: () => (s() > 1 || Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) == 1) ? true : false, radius: 1, color: 'orange', fillOpacity: 0, name: 'β' });
<jsxgraph width="100%" aspect-ratio="1 / 1" title="Snell's law" description="This construction was copied from JSXGraph examples database: BTW HERE SHOULD BE A GENERATED LINKuseGlobalJS="false"> /* This example is licensed under a Creative Commons Attribution ShareAlike 4.0 International License. https://creativecommons.org/licenses/by-sa/4.0/ Please note you have to mention The Center of Mobile Learning with Digital Technology in the credits. */ var board = JXG.JSXGraph.initBoard(BOARDID, { boundingbox: [-5, 5, 5, -5], axis: false, keepaspectratio: true }); // Line l1 as an interface between two environments, green, with the index of refraction // n_1, and the blue, with the index of refraction n_2. var M = board.create('point', [-4, 0], { name: 'M', visible: false, fixed: true }); var I = board.create('point', [0, 0], { name: 'I', size: 1, fixed: true }); var l1 = board.create('line', [M, I]); var ineq1 = board.create('inequality', [l1], { fillColor: 'green' }); var ineq2 = board.create('inequality', [l1], { inverse: true, fillColor: 'blue' }); // Normal line n with auxiliary points N and O that allows us to determine // the angles of incidence (α) and refraction (β), respectively var n = board.create('perpendicular', [l1, I], { name: 'n', color: 'black', dash: "2", strokeWidth: 1 }); var N = board.create('glider', [0, 4, n], { name: 'N', visible: false }); var O = board.create('glider', [0, -4, n], { name: 'O', visible: false }); // a light source L var L = board.create('point', [-3, 4], { name: 'L', color: 'red', size: 3 }); // Position of the light source L is limited to the green environment var xL, yL; L.on('drag', function() { if (L.Y() < 0) { L.moveTo([xL, yL], 0); } xL = L.X(); yL = L.Y(); }); // r1, the incident light ray var r1 = board.create('segment', [L, I], { strokeColor: 'orange', strokeWidth: 4 }); // Sliders to control indexes of refraction var n_1 = board.create('slider', [[-4, -3], [-2, -3], [1, 1, 3]], { name: 'n_1', snapWidth: 0.01 }); var n_2 = board.create('slider', [[-4, -4], [-2, -4], [1, 1, 3]], { name: 'n_2', snapWidth: 0.01 }); // The value of s controls the kind of refraction/reflection, if s > 1 the total reflection occurs // (numerically it is the absolute value of the sine of the angle of refraction) var s = () => (n_1.Value() / n_2.Value()) * Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))).toFixed(6); // Two possible points through which the modified ray passes, B for the reflected ray and C for the refracted one var B = board.create('point', [ () => -L.X(), () => L.Y() ], { visible: () => (s() > 1 || Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) == 1) ? true : false, name: 'R_1', face: 'o', size: 1 }); var C = board.create('point', [ () => 5 * (n_1.Value() / n_2.Value()) * Math.sin(JXG.Math.Geometry.angle(N, I, L)), () => -5 * Math.cos(Math.asin((n_1.Value() / n_2.Value()) * Math.sin(JXG.Math.Geometry.angle(N, I, L)))) ], { visible: () => (s() <= 1 && Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) != 1) ? true : false, name: 'R_2', face: 'o', size: 1 }); // Reflected (r2) and refracted (r3) ray var r2 = board.create('segment', [I, B], { visible: () => (s() > 1 || Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) == 1) ? true : false, strokeColor: 'orange', strokeWidth: 4, lastArrow: { type: 1, size: 3 } }); var r3 = board.create('segment', [I, C], { visible: () => (s() <= 1 && Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) != 1) ? true : false, strokeColor: 'orange', strokeWidth: 4, lastArrow: { type: 1, size: 3 } }); // Angles of impact (angle 1), refraction (angle2) and reflection (angle3), respectively var angle1 = board.create('nonreflexangle', [N, I, L], { radius: 1, color: 'orange', fillOpacity: 0, name: 'α' }); var angle2 = board.create('nonreflexangle', [O, I, C], { visible: () => (s() <= 1 && Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) != 1) ? true : false, radius: 1, color: 'orange', fillOpacity: 0, name: 'β' }); var angle3 = board.create('nonreflexangle', [B, I, N], { visible: () => (s() > 1 || Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) == 1) ? true : false, radius: 1, color: 'orange', fillOpacity: 0, name: 'β' }); </jsxgraph>
// Define the id of your board in BOARDID var board = JXG.JSXGraph.initBoard(BOARDID, { boundingbox: [-5, 5, 5, -5], axis: false, keepaspectratio: true }); // Line l1 as an interface between two environments, green, with the index of refraction // n_1, and the blue, with the index of refraction n_2. var M = board.create('point', [-4, 0], { name: 'M', visible: false, fixed: true }); var I = board.create('point', [0, 0], { name: 'I', size: 1, fixed: true }); var l1 = board.create('line', [M, I]); var ineq1 = board.create('inequality', [l1], { fillColor: 'green' }); var ineq2 = board.create('inequality', [l1], { inverse: true, fillColor: 'blue' }); // Normal line n with auxiliary points N and O that allows us to determine // the angles of incidence (α) and refraction (β), respectively var n = board.create('perpendicular', [l1, I], { name: 'n', color: 'black', dash: "2", strokeWidth: 1 }); var N = board.create('glider', [0, 4, n], { name: 'N', visible: false }); var O = board.create('glider', [0, -4, n], { name: 'O', visible: false }); // a light source L var L = board.create('point', [-3, 4], { name: 'L', color: 'red', size: 3 }); // Position of the light source L is limited to the green environment var xL, yL; L.on('drag', function() { if (L.Y() < 0) { L.moveTo([xL, yL], 0); } xL = L.X(); yL = L.Y(); }); // r1, the incident light ray var r1 = board.create('segment', [L, I], { strokeColor: 'orange', strokeWidth: 4 }); // Sliders to control indexes of refraction var n_1 = board.create('slider', [[-4, -3], [-2, -3], [1, 1, 3]], { name: 'n_1', snapWidth: 0.01 }); var n_2 = board.create('slider', [[-4, -4], [-2, -4], [1, 1, 3]], { name: 'n_2', snapWidth: 0.01 }); // The value of s controls the kind of refraction/reflection, if s > 1 the total reflection occurs // (numerically it is the absolute value of the sine of the angle of refraction) var s = () => (n_1.Value() / n_2.Value()) * Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))).toFixed(6); // Two possible points through which the modified ray passes, B for the reflected ray and C for the refracted one var B = board.create('point', [ () => -L.X(), () => L.Y() ], { visible: () => (s() > 1 || Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) == 1) ? true : false, name: 'R_1', face: 'o', size: 1 }); var C = board.create('point', [ () => 5 * (n_1.Value() / n_2.Value()) * Math.sin(JXG.Math.Geometry.angle(N, I, L)), () => -5 * Math.cos(Math.asin((n_1.Value() / n_2.Value()) * Math.sin(JXG.Math.Geometry.angle(N, I, L)))) ], { visible: () => (s() <= 1 && Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) != 1) ? true : false, name: 'R_2', face: 'o', size: 1 }); // Reflected (r2) and refracted (r3) ray var r2 = board.create('segment', [I, B], { visible: () => (s() > 1 || Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) == 1) ? true : false, strokeColor: 'orange', strokeWidth: 4, lastArrow: { type: 1, size: 3 } }); var r3 = board.create('segment', [I, C], { visible: () => (s() <= 1 && Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) != 1) ? true : false, strokeColor: 'orange', strokeWidth: 4, lastArrow: { type: 1, size: 3 } }); // Angles of impact (angle 1), refraction (angle2) and reflection (angle3), respectively var angle1 = board.create('nonreflexangle', [N, I, L], { radius: 1, color: 'orange', fillOpacity: 0, name: 'α' }); var angle2 = board.create('nonreflexangle', [O, I, C], { visible: () => (s() <= 1 && Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) != 1) ? true : false, radius: 1, color: 'orange', fillOpacity: 0, name: 'β' }); var angle3 = board.create('nonreflexangle', [B, I, N], { visible: () => (s() > 1 || Math.abs(Math.sin(JXG.Math.Geometry.angle(N, I, L))) == 1) ? true : false, radius: 1, color: 'orange', fillOpacity: 0, name: 'β' });
This example is licensed under a Creative Commons Attribution ShareAlike 4.0 International License. Please note you have to mention The Center of Mobile Learning with Digital Technology in the credits.