|
// constant options |
|
const focalDepth = 80; |
|
const focalPoint = 256; |
|
|
|
|
|
// variables |
|
var centreX; |
|
var centreY; |
|
var mouseX; |
|
var mouseY; |
|
var spawnX; |
|
var spawnY; |
|
var frameCount=0; |
|
|
|
// variables |
|
const maxpoints = 4096; |
|
var pointcloud = []; |
|
|
|
// uniform distribution of a randomized unit vector |
|
function RandomNormal() |
|
{ |
|
var theta = Math.random() * Math.PI * 2; |
|
var nz = 1 - 2*Math.random(); |
|
var phi = Math.acos(nz); |
|
var nx = Math.sin(theta)*Math.sin(phi); |
|
var ny = Math.cos(theta)*Math.sin(phi); |
|
|
|
return {x:nx, y:ny, z:nz}; |
|
} |
|
|
|
function InitRandomDistribution() |
|
{ |
|
for (var i=0; i<maxpoints;i++) |
|
{ |
|
pointcloud.push(RandomNormal()); |
|
} |
|
} |
|
|
|
var theta = 0; |
|
var phi = 0; |
|
function RenderRandomDistribution() |
|
{ |
|
theta+=0.01; |
|
phi+=0.01; |
|
var scale = 20* canvas.height/500; |
|
context.beginPath(); |
|
for (var i=0; i<pointcloud.length; i++) |
|
{ |
|
var point = pointcloud[i]; |
|
|
|
var x1 = point.x * Math.cos(theta) - point.z*Math.sin(theta); |
|
var z1 = point.x * Math.sin(theta) + point.z*Math.cos(theta); |
|
var y1 = point.y * Math.cos(phi) - z1*Math.sin(phi); |
|
var z1 = point.y * Math.sin(phi) + z1*Math.cos(phi); |
|
x1*=scale; |
|
z1*=scale; |
|
y1*=scale; |
|
if (z1+focalDepth<0) continue; |
|
var depth = focalPoint*3 / (z1 + focalDepth ); |
|
|
|
var x = x1 * depth + centreX; |
|
var y = y1 * depth + centreY; |
|
var sz = depth * 0.2; |
|
|
|
// fill a rect |
|
context.rect(x,y, sz, sz); |
|
} |
|
|
|
context.fillStyle = '#ffffff'; |
|
context.fill(); |
|
} |
|
|
|
// initialization |
|
|
|
function init() |
|
{ |
|
// setup canvas and context |
|
canvas = document.getElementById('uniform distribution'); |
|
context = canvas.getContext('2d'); |
|
|
|
// set canvas to be window dimensions |
|
resize(); |
|
|
|
// create event listeners |
|
canvas.addEventListener('mousemove', mouseMove); |
|
canvas.addEventListener('click', mouseClick); |
|
window.addEventListener('resize', resize); |
|
|
|
// initialze variables |
|
InitRandomDistribution(); |
|
} |
|
|
|
|
|
// input functions |
|
|
|
function mouseMove(event) |
|
{ |
|
var rect = canvas.getBoundingClientRect(); |
|
|
|
mouseX = event.clientX - rect.left, |
|
mouseY = event.clientY - rect.top |
|
} |
|
|
|
function mouseClick() |
|
{ |
|
} |
|
|
|
function resize() |
|
{ |
|
canvas.width = window.innerWidth; |
|
canvas.height = window.innerHeight; |
|
// compute centre of screen |
|
centreX = canvas.width/2; |
|
centreY = canvas.height/2; |
|
} |
|
|
|
|
|
// rendering functions |
|
|
|
function render() |
|
{ |
|
|
|
context.fillStyle = 'black'; |
|
context.clearRect(0, 0, canvas.width, canvas.height); |
|
|
|
RenderRandomDistribution(); |
|
|
|
context.globalAlpha = 1.0; |
|
context.font = '20pt Calibri'; |
|
context.fillStyle = 'rgb(255,255,0)'; |
|
context.textAlign = "center"; |
|
context.fillText('Random Normal', canvas.width/2, 25); |
|
context.fillText('Or randomized unit vector with a uniform distribution', canvas.width/2, 45); |
|
context.fillText('alternatively, even distribution of points on a the surface of a sphere', canvas.width/2, canvas.height-25); |
|
|
|
} |
|
|
|
// movement functions |
|
|
|
function update() |
|
{ |
|
} |
|
|
|
// per frame tick functions |
|
|
|
function animate() |
|
{ |
|
frameCount++; |
|
// movement update |
|
update(); |
|
// render update |
|
render(); |
|
// trigger next frame |
|
requestAnimationFrame(animate); |
|
} |
|
|
|
|
|
|
|
// entry point |
|
init(); |
|
animate();</script> |