Skip to content

Instantly share code, notes, and snippets.

@divarvel
Created October 21, 2019 09:18
Show Gist options
  • Save divarvel/608e1aaef1a780f6ca5d64eedcbb8db5 to your computer and use it in GitHub Desktop.
Save divarvel/608e1aaef1a780f6ca5d64eedcbb8db5 to your computer and use it in GitHub Desktop.
/*
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