Last active
January 2, 2016 18:39
-
-
Save 9re/8345006 to your computer and use it in GitHub Desktop.
calculation of refraction
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>refract test</title> | |
<link rel="stylesheet" href="style.css" type="text/css" media="screen" /> | |
</head> | |
<body> | |
<canvas width="465" height="465" id="world"></canvas> | |
<div class="input"> | |
n1 : <input type="text" id="n1" value="1.000293" /> | |
n2 : <input type="text" id="n2" value="1.333" /> | |
</div> | |
<script type="text/javascript" src="index.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var canvas = document.getElementById('world'), | |
context = canvas.getContext('2d'), | |
width = canvas.width, | |
height = canvas.height, | |
center, n1, n2 | |
; | |
var VERTEX0, | |
VERTEX1, | |
VERTEX2, | |
VERTEX3, | |
RI = {} | |
; | |
function Vec2(x, y) { | |
this.x = x; | |
this.y = y; | |
} | |
Vec2.prototype = { | |
minus : function (other) { | |
return new Vec2(this.x - other.x, this.y - other.y); | |
}, | |
plus : function (other) { | |
return new Vec2(this.x + other.x, this.y + other.y); | |
}, | |
scalar : function (k) { | |
return new Vec2(k * this.x, k * this.y); | |
}, | |
crossProd : function (other) { | |
return this.x * other.y - this.y * other.x; | |
}, | |
dot : function (other) { | |
return this.x * other.x + this.y * other.y; | |
}, | |
normalize : function () { | |
var len = Math.sqrt(this.dot(this)); | |
this.x /= len; | |
this.y /= len; | |
} | |
}; | |
function findIntersection(p0, p1) { | |
var p; | |
p = hitTest(p0, p1, VERTEX0, VERTEX1); | |
if (p) { | |
return p; | |
} | |
p = hitTest(p0, p1, VERTEX1, VERTEX2); | |
if (p) { | |
return p; | |
} | |
p = hitTest(p0, p1, VERTEX2, VERTEX3); | |
if (p) { | |
return p; | |
} | |
p = hitTest(p0, p1, VERTEX3, VERTEX0); | |
if (p) { | |
return p; | |
} | |
return undefined; | |
} | |
function hitTest(p0, p1, q0, q1) { | |
var p = p1.minus(p0); | |
var v = q1.minus(q0).crossProd(p); | |
if (v === 0) { | |
console.log("v === 0"); | |
return undefined; | |
} | |
var pq = p0.minus(q0); | |
var u = pq.crossProd(p); | |
var t = u / v; | |
if (t < 0 || t > 1) { | |
return undefined; | |
} | |
var l = pq.crossProd(q1.minus(q0)); | |
var k = l / v; | |
if (k < 0) { | |
return undefined; | |
} | |
var s = 1 - t; | |
return q0.scalar(s).plus(q1.scalar(t)); | |
} | |
function refract(n1, n2, a, N) { | |
var n = n2 / n1; | |
var k = a.dot(N); | |
var c = 1 - n * n * (1 - k * k); | |
var res = undefined; | |
if (c >= 0) { | |
c = Math.sqrt(c); | |
var t = n * k - c; | |
res = new Vec2( | |
n * a.x + t * N.x, | |
n * a.y + t * N.y | |
); | |
} | |
return res; | |
} | |
function renderLine(p0, p1, strokeColor) { | |
context.beginPath(); | |
context.strokeStyle = strokeColor; | |
context.moveTo(p0.x, p0.y); | |
context.lineTo(p1.x, p1.y); | |
context.stroke(); | |
} | |
function onmousemove(e) { | |
var mouse = new Vec2(e.x, e.y); | |
var p = findIntersection(center, mouse); | |
context.clearRect(0, 0, width, height); | |
renderLine(new Vec2(center.x, VERTEX0.y), new Vec2(center.x, VERTEX2.y), '#000'); | |
renderLine(new Vec2(VERTEX0.x, center.y), new Vec2(VERTEX2.x, center.y), '#000'); | |
renderLine(center, p, '#ff7700'); | |
var a = center.minus(mouse); | |
a.normalize(); | |
var refracted = refract(n1, n2, a, new Vec2(0, 1)); | |
p = findIntersection(center, center.plus(refracted)); | |
renderLine(center, p, '#77ff00'); | |
} | |
function updateN1 () { | |
var input = document.getElementById('n1'); | |
n1 = input.value; | |
} | |
function updateN2 () { | |
var input = document.getElementById('n2'); | |
n2 = input.value; | |
} | |
function init() { | |
center = new Vec2(width / 2, height / 2); | |
context.lineWidth = 2; | |
canvas.addEventListener('mousemove', onmousemove); | |
updateN1(); | |
updateN2(); | |
document | |
.getElementById('n1') | |
.addEventListener('input', updateN1); | |
document | |
.getElementById('n2') | |
.addEventListener('input', updateN2); | |
VERTEX0 = new Vec2(0, 0); | |
VERTEX1 = new Vec2(465, 0); | |
VERTEX2 = new Vec2(465, 465); | |
VERTEX3 = new Vec2(0, 465); | |
onmousemove(VERTEX0); | |
} | |
init(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
html, body { | |
margin : 0; | |
border : 0; | |
padding : 0; | |
} | |
.input { | |
background : rgba(0, 0, 0, 0.7); | |
width : 465px; | |
color : white; | |
position : absolute; | |
top : 0px; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment