Last active
May 2, 2021 16:44
-
-
Save derekmc/7975e944f5c1e19a8fbec5d6ecf2b29d to your computer and use it in GitHub Desktop.
This file contains hidden or 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
<canvas id="Canvas"></canvas> | |
<script> | |
Canvas.width = window.innerWidth - 16; | |
Canvas.height = window.innerHeight - 16; | |
let Ctx = Canvas.getContext("2d"); | |
let X=0, Y=0; | |
let Distance=3; | |
let PointSize=0.015; | |
let LineWidth= 0.005; | |
let Center = [0.65,0.8,0.5]; | |
const EPS = 0.00001; | |
window.addEventListener("load", Init); | |
document.body.addEventListener("keydown", KeyPress); | |
let Drawing = null | |
function Init(){ | |
let cube1 = Cube([0,0,0], 1); | |
let cube2 = Cube([0,0,4], 1); | |
let cube3 = Cube([1.25,1.25,4], 1); | |
let cube4 = Cube([1.25,0,4], 1); | |
Drawing = MergeDrawings(cube1, cube2, cube3,cube4); | |
//console.log(Drawing); | |
Ctx.save(); | |
RescaleCanvas(); | |
Draw(Drawing, Center); | |
} | |
function RescaleCanvas(){ | |
let w2 = Canvas.width/2, h2 = Canvas.height/2; | |
let s2 = Math.min(w2, h2); | |
let S2 = Math.max(w2, h2); | |
Ctx.translate(w2,h2); | |
Ctx.scale(s2, -s2); | |
} | |
function Cube(center, side){ | |
let points = []; | |
let lines = []; | |
let s = side/2; | |
for(let i=0; i<8; ++i){ | |
let p = []; | |
p.push(center[0] + (i&1? s : -s)); | |
p.push(center[1] + (i&2? s : -s)); | |
p.push(center[2] + (i&4? s : -s)); | |
points.push(p); | |
} | |
// create all lines hamming distance 1 | |
for(let a=0; a<7; ++a){ | |
for(let b=a+1; b<8; ++b){ | |
let different = 0; | |
if(points[a][0] != points[b][0]) ++different; | |
if(points[a][1] != points[b][1]) ++different; | |
if(points[a][2] != points[b][2]) ++different; | |
if(different == 1) lines.push([a,b]); | |
} | |
} | |
return {points, lines}; | |
} | |
// similar triangles | |
// from (x, z) | |
// to (xx=?, zz) | |
// xx = zz * x/z | |
// depth of screen | |
//get progressive scalars for how much to scale each point | |
// result is a flattened array of all projected points. | |
function ProjectPoints(result, points, center, depth){ | |
if(result == null) result = []; | |
for(let i=0; i<points.length; ++i){ | |
let p = points[i]; | |
let x = p[0] - center[0]; | |
let y = p[1] - center[1]; | |
let z = p[2] - center[2]; | |
let s = (z > -depth + EPS)? depth / (z + depth) : 1000 * 1000; | |
if(!(z > -depth + EPS)) console.log("behind screen"); | |
result[2*i] = s*x; | |
result[2*i + 1] = s*y; | |
} | |
return result; | |
} | |
function Copy(x){ | |
return JSON.parse(JSON.stringify(x)); | |
} | |
function MergeDrawings(...drawings){ | |
//console.log(drawings); | |
let points = []; | |
let lines = []; | |
let n = 0; | |
for(let drawing of drawings){ | |
//console.log('drawing', drawing); | |
for(let i=0; i<drawing.points.length; ++i){ | |
points.push(drawing.points[i].slice(0)); } | |
for(let i=0; i<drawing.lines.length; ++i){ | |
lines.push(drawing.lines[i].map(x => x + n)); } | |
n += drawing.points.length; | |
} | |
return {points, lines}; | |
} | |
function Dot(a, b){ | |
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; | |
} | |
function Draw(drawing, center){ | |
let array = []; | |
Ctx.fillStyle="#e4e4e4"; | |
Ctx.fillRect(-1, -1, 2, 2); | |
Ctx.fillStyle="#000"; | |
ProjectPoints(array, drawing.points, center, Distance); | |
for(let i=0; i<array.length; i += 2){ | |
let x = array[i]; | |
let y = array[i+1]; | |
//console.log(x, y); | |
Ctx.fillRect(x-PointSize/2,y-PointSize/2, PointSize, PointSize); | |
} | |
Ctx.beginPath(); | |
Ctx.lineWidth = LineWidth; | |
for(let i=0; i<drawing.lines.length; ++i){ | |
let a = drawing.lines[i][0]; | |
let b = drawing.lines[i][1]; | |
//console.log(array[2*a], array[2*a + 1]); | |
//console.log(array[2*b], array[2*b + 1]); | |
Ctx.moveTo(array[2*a], array[2*a + 1]); | |
Ctx.lineTo(array[2*b], array[2*b + 1]); | |
} | |
Ctx.stroke(); | |
// Ctx.fillStyle="#000"; | |
// Ctx.fillRect(-1/2, 0, 1, 1); | |
// Ctx.fillStyle="#e4e4e4"; | |
// Ctx.fillRect(0, 0, Canvas.width, Canvas.height); | |
// Ctx.fillStyle="#000"; | |
// Ctx.fillRect(X,Y,40,40); | |
} | |
function KeyPress(){ | |
X = (X + 10) % (Canvas.width - 40); | |
Y = Math.random() * (Canvas.height - 40); | |
Draw(); | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment