JSFiddle - React, Tailwind, and code Playground
by Stanislav Doronin
HTML
<canvas id='myCanvas'> </canvas>
JavaScript
// n - показатель преломления
function trace_rays(n) {
var points = [];
for (var i=-0.95; i<1; i=i+0.05) {
var a = Math.acos(i);
var b = Math.PI / 2.0 - a;
var b1 = Math.asin(Math.sin(b)/n);
var x0 = i;
var y0 = 2;
var x1 = i;
var y1 = Math.sin(a);
var b1_ = b1 - b;
var l = 2 * Math.sin(Math.PI/2.0 - b1);
var x2 = x1 + Math.sin(b1_) * l;
var y2 = y1 - Math.cos(b1_) * l;
var b3 = Math.PI/2 + Math.acos(x2);
var b3_ = Math.PI + b3 + b;
var x3 = x2 - Math.sin(b3_) * 2;
var y3 = y2 - Math.cos(b3_) * 2;
var ray = [[x0,y0],[x1,y1],[x2,y2],[x3,y3]];
var ortl = 0.1;
var ort1 = [[x1 + Math.sin(b)*ortl, y1 + Math.cos(b)*ortl], [x1 - Math.sin(b)*ortl, y1 - Math.cos(b)*ortl]];
var ort2 = [[x2 + Math.sin(b3)*ortl, y2 + Math.cos(b3)*ortl], [x2 - Math.sin(b3)*ortl, y2 - Math.cos(b3)*ortl]];
points.push(ray,ort1,ort2);
}
return points;
}
function draw_glass(ctx,sx,sy,k) {
ctx.beginPath();
ctx.arc(sx*k, sy*k, k, 0, 2 * Math.PI, false);
ctx.stroke();
}
function draw_rays(ctx,sx,sy,k,rays) {
while (rays.length>0) {
var ray = rays.shift();
var p = ray.shift();
ctx.beginPath();
ctx.moveTo((p[0]+sx)*k, (p[1]+sy)*k);
while (ray.length>0) {
p = ray.shift();
ctx.lineTo((p[0]+sx)*k, (p[1]+sy)*k);
}
ctx.stroke();
}
}
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext('2d');
canvas.width = 1000;
canvas.height = 800;
var rays1 = trace_rays(1.33);
var rays2 = trace_rays(1);
var k = 100;
var sx = 2;
var sy = 3;
draw_rays(ctx,sx,sy,k,rays2);
draw_glass(ctx,sx,sy,k);
sx = 4.2;
draw_rays(ctx,sx,sy,k,rays1);
draw_glass(ctx,sx,sy,k);