Created
October 21, 2019 09:18
-
-
Save divarvel/608e1aaef1a780f6ca5d64eedcbb8db5 to your computer and use it in GitHub Desktop.
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
/* | |
Data format: the triangles are represented by a matrix. Each odd line is shifted down by 1/2. | |
0 represents nothing, 7 represents a full triangle. | |
[[7,7,7], [7,0,0]] translates to: | |
|\ |\ | |
| \ | \ | |
| /|\ | / | |
|/ | \|/ | |
|\ | / | |
| \|/ | |
| / | |
|/ | |
Numbers between 1 and 6 represent partial triangles | |
1: | | |
2: \ | |
3: |\ | |
4: / | |
5: |/ | |
6: > | |
For each beam of a triangle, some lines are always visible. | |
The trick is to display the lines that are visible sometimes. | |
To do that, we consider each summit of a triangle: | |
N | |
|\E | |
|/ | |
S | |
For each summit, there are 6 outgoing beams: | |
NW N NE | |
\|/ | |
/|\ | |
SW S SE | |
Two of them belong to the current triangle, four of them belong to the neighbours. | |
So the trick is to compute the extra lines for each beam combination. There are six beams, | |
either here or not here, so that gives 2⁶ = 64 possibilities. Let's hope we can factor things out. | |
He're, we'll consider only the top corner of a triangle. So the only beams we're fully drawing are | |
S and SE. The other beams will be drawn by the neighbors. We only have to care about the boundaries. | |
*/ | |
// bar width | |
const w = 20; | |
// pattern width | |
const W = 100; | |
const p = (x,y) => [x,y] | |
const l = (b,e) => [b,e] | |
const beams | |
= { S: [ l(p(-w,1.5*w), p(-w,W-0.5*w)) | |
, l(p(0,w), p(0,W-w)) | |
, l(p(w,1.5*w), p(w,W-0.5*w)) | |
] | |
, SE: [ l(p(w, 1.5*w), p(W-2*w,0.5*W)) | |
, l(p(w, 0.5*w), p(W-w,0.5*W-0.5*w)) | |
, l(p(2*w,0), p(W-w, 0.5*W-1.5*w)) | |
] | |
} | |
const boundaries = (N,NE,SE,S,SW,NW) => ( | |
[ [l(p(0,0),p(0,w)), (SW&&SE)] // todo | |
, [l(p(0,0),p(w,-0.5*w)), (N&&SE)||((SW||NE)&&!N)] // todo | |
, [l(p(0,0),p(w,0.5*w)), SE ] | |
, [l(p(0,w),p(w,0.5*w)), (N||NW||SW||NE)&&!S&&!SE] | |
, [l(p(0,w),p(w,1.5*w)), SE ] | |
, [l(p(w,-0.5*w),p(w,0.5*w)), (N||S||SW||NW)&&!SE&&!NE] | |
, [l(p(w,0.5*w),p(w,1.5*w)), S && !SE ] | |
, [l(p(w,-0.5*w),p(2*w,0)), SE ] | |
, [l(p(w,0.5*w),p(2*w,0)), NE && !SE ] | |
]) | |
const getBeam = (x)=> beams[x] || []; | |
const getLines = ({N,NE,SE,S,SW,NW}) => { | |
const bs = [].concat(getBeam(S && "S"),getBeam(SE && "SE")); | |
const bounds = boundaries(N,NE,SE,S,SW,NW).filter(([_,p]) => p).map(([l,_]) => l); | |
return [].concat(bs, bounds); | |
} | |
const canvas = document.getElementById('main'); | |
canvas.height = window.innerHeight; | |
canvas.width = window.innerWidth; | |
const ctx = canvas.getContext('2d'); | |
ctx.fillStyle = "white"; | |
ctx.fillRect(0, 0, canvas.width, canvas.height); | |
const drawLine= ([ox,oy]) => ([[x1,y1],[x2,y2]]) => { | |
ctx.moveTo(ox + x1, oy + y1); | |
ctx.lineTo(ox + x2, oy + y2); | |
ctx.stroke(); | |
} | |
const drawLines = (offset) => (lines) => { | |
lines.forEach(drawLine(offset)) | |
} | |
const SES = { | |
N: false, | |
NE: false, | |
SE: true, | |
S: true, | |
SW: false, | |
NW: false | |
} | |
const draw = (o) => { | |
const lines = getLines(o); | |
ctx.clearRect(0,0, 1000, 1000); | |
console.log(lines); | |
drawLines([100,100])(lines); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment