Skip to content

Instantly share code, notes, and snippets.

@felipetavares
Created November 16, 2018 19:19
Show Gist options
  • Save felipetavares/c7fdf35c5eff7fa30c8f3685b826aa82 to your computer and use it in GitHub Desktop.
Save felipetavares/c7fdf35c5eff7fa30c8f3685b826aa82 to your computer and use it in GitHub Desktop.
Polygon Generator: given a set of tile positions create a polygon from its boundary
function cantor(x, y) {
return (x+y)/2*(x+y+1)+y;
}
function decantor(z) {
let w = Math.floor((Math.sqrt(8*z+1)-1)/2);
let t = (w*w+w)/2;
return {
y: z-t,
x: w-(z-t)
};
}
function render(tiles) {
var grid = [];
for (let tile of tiles) {
grid[cantor(tile[0], tile[1])] = true;
}
return grid;
}
function find_center(poly) {
var center = { x: 0, y: 0 };
for (let p of poly) {
center.x += p.x/poly.length;
center.y += p.y/poly.length;
}
return center;
}
/**
* Converts an array containing grid tiles
* into an ordered list of points for drawing
* said tiles.
*
* @param {tiles} input list of tiles positions
* @param {side} grid unit size
*/
function tiles2poly(tiles, side) {
let grid = render(tiles);
var poly = new Set([]);
for (var g=0;g<grid.length;g++) {
if (grid[g] == true) {
let p = decantor(g);
var all_neighbour = true;
for (var dx=-1;dx<=1;dx++) {
for (var dy=-1;dy<=1;dy++) {
if (dx != 0 && dy != 0) {
if (grid[cantor(Math.floor(p.x+dx), Math.floor(p.y+dy))] != true) {
all_neighbour = false;
}
}
}
}
if (!all_neighbour) {
poly.add(g);
poly.add(cantor(p.x+1, p.y));
poly.add(cantor(p.x, p.y+1));
poly.add(cantor(p.x+1, p.y+1));
}
}
}
poly = Array.from(poly).map(function (z) {
let p = decantor(z);
return {
x: p.x*side,
y: p.y*side
};
});
let center = find_center(poly);
poly.sort(function (a, b) {
return -((a.x-center.x)*(b.y-center.y)-(b.x-center.x)*(a.y-center.y));
});
return poly;
}
console.log(tiles2poly([ [0, 0], [0, 1], [1, 1] ], 1));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment