Snell's law

From JSXGraph Wiki
Revision as of 11:08, 15 July 2020 by A WASSERMANN (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Refraction of a light ray emanating from the source L at the interface between two environments of different refractive indices, n1, n2.

Reference: https://en.wikipedia.org/wiki/Snell%27s_law. Construction by by Roman Hašek.

The complete JavaScript code

    var board = JXG.JSXGraph.initBoard('box', {boundingbox: [-5, 5, 5, -5], axis:false});

    // 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]);
    ineq1 = board.create('inequality', [l1], {fillColor: 'green'});
    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 = function() { return (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', [
               function(){ return -L.X(); }, 
               function(){ return L.Y(); }
            ], {
               visible: function(){
                   return (s()>1 || Math.abs(Math.sin(JXG.Math.Geometry.angle(N,I,L)))==1)? true : false;
               }, name:'R_1', face:'o', size:1, visible: false
            });
    var C = board.create('point', [
               function(){ return 5*(n_1.Value()/n_2.Value())*Math.sin(JXG.Math.Geometry.angle(N,I,L)); },
               function(){
                   return -5*Math.cos(Math.asin((n_1.Value()/n_2.Value()) * Math.sin(JXG.Math.Geometry.angle(N,I,L)))); }
            ], {
               visible: function(){
                   return (s()<=1 && Math.abs(Math.sin(JXG.Math.Geometry.angle(N,I,L)))!=1)? true : false;
               }, name:'R_2', face:'o', size:1, visible:false
            });    

    // Reflected (r2) and refracted (r3) ray
    var r2 = board.create('segment', [I, B], {
               visible: function(){
                   return (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: function(){
                   return (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: '&alpha;'});
    var angle2 = board.create('nonreflexangle',[O,I,C], {
               visible: function(){
                   return (s()<=1 && Math.abs(Math.sin(JXG.Math.Geometry.angle(N,I,L)))!=1)? true : false;
               }, radius:1, color:'orange', fillOpacity: 0, name: '&beta;'
           });
    var angle3 = board.create('nonreflexangle',[B,I,N], {
               visible:function(){
                   return (s()>1 || Math.abs(Math.sin(JXG.Math.Geometry.angle(N,I,L)))==1)? true : false;
               }, radius:1, color:'orange', fillOpacity: 0, name: '&beta;'
           });