Last active
August 29, 2015 14:16
-
-
Save fabiovalse/dca8ad12204c6db9d588 to your computer and use it in GitHub Desktop.
Hexagonal Grid: how do you find which hexagon a point is in?
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
svg { | |
background: #fff; | |
} | |
.hexagon path { | |
fill: #ddd; | |
stroke: #000; | |
stroke-width: .5px; | |
} | |
.label { | |
pointer-events: none; | |
font-family: sans-serif; | |
text-anchor: middle; | |
} | |
.cursor { | |
fill: none; | |
stroke: red; | |
stroke-width: 3px; | |
pointer-events: none; | |
} |
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title></title> | |
<link type="text/css" href="index.css" rel="stylesheet"/> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script src="http://d3js.org/d3.hexbin.v0.min.js?5c6e4f0"></script> | |
</head> | |
<body> | |
<script src="index.js"></script> | |
</body> | |
</html> |
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
var width = 960; | |
height = 500; | |
var points = [], radius = 30; | |
var cos30 = Math.sqrt(3)/2; | |
var sin30 = 1/2; | |
var rows = Math.ceil(height/(3/2*radius)); | |
var columns = Math.ceil(width/(cos30*radius*2)); | |
var gridHeight = sin30*radius*3; | |
var gridWidth = cos30*radius*2; | |
var c = sin30 * radius; | |
var m = c / (gridWidth/2); | |
for (i = 0; i < rows; i++) { | |
for (j = 0; j < columns; j++) { | |
points.push({"i": i, "j": j}); | |
} | |
} | |
var getHexagon = function (point) { | |
point[0] = point[0] + cos30*radius; | |
point[1] = point[1] + radius; | |
var row = Math.floor(point[1] / gridHeight); | |
var column; | |
var rowIsOdd = (row % 2 == 1); | |
if (rowIsOdd) | |
column = Math.floor((point[0] - gridWidth/2) / gridWidth); | |
else | |
column = Math.floor(point[0] / gridWidth); | |
var relY = point[1] - (row * gridHeight); | |
var relX; | |
if (rowIsOdd) | |
relX = (point[0] - (column * gridWidth)) - gridWidth/2; | |
else | |
relX = point[0] - (column * gridWidth); | |
// Work out if the point is above either of the hexagon's top edges | |
if (relY < (-m * relX) + c) {// LEFT edge | |
row--; | |
if (!rowIsOdd) | |
column--; | |
} | |
else if (relY < (m * relX) - c) {// RIGHT edge | |
row--; | |
if (rowIsOdd) | |
column++; | |
} | |
return [row, column]; | |
}; | |
var vis = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
var cursor = vis.append("path") | |
.attr("class", "cursor") | |
.attr("d", function(r) {return "M0,"+radius+" L"+(cos30*radius)+","+(sin30*radius)+" L"+(cos30*radius)+","+(-sin30*radius)+" L0,"+(-radius)+" L"+(-cos30*radius)+","+(-sin30*radius)+" L"+(-cos30*radius)+","+(sin30*radius)+" Z";}); | |
var get_coordinates = function(d, i) { | |
h = getHexagon(d3.mouse(this)); | |
if (h[0] % 2 === 0) | |
cursor.attr("transform", "translate(" + (h[1]*cos30*radius*2) + "," + (h[0]*3/2*radius) + ")"); | |
else | |
cursor.attr("transform", "translate(" + (h[1]*(cos30*radius*2)+(cos30*radius)) + "," + (h[0]*3/2*radius) + ")"); | |
}; | |
var hexagon_layer = vis.insert("g", ":last-child").on('mouseover', get_coordinates); | |
var hexagon = hexagon_layer.selectAll(".hexagon") | |
.data(points); | |
var enter_hexagon = hexagon.enter().append("g") | |
.attr("class", "hexagon") | |
.attr("transform", function(d) { | |
if (d.i % 2 === 0) | |
return "translate(" + (d.j*cos30*radius*2) + "," + (d.i*3/2*radius) + ")"; | |
else | |
return "translate(" + (d.j*(cos30*radius*2)+(cos30*radius)) + "," + (d.i*3/2*radius) + ")"; | |
}); | |
enter_hexagon.append("path") | |
.attr("d", function(r) {return "M0,"+radius+" L"+(cos30*radius)+","+(sin30*radius)+" L"+(cos30*radius)+","+(-sin30*radius)+" L0,"+(-radius)+" L"+(-cos30*radius)+","+(-sin30*radius)+" L"+(-cos30*radius)+","+(sin30*radius)+" Z";}); | |
enter_hexagon.append("text") | |
.attr("class", "label") | |
.attr("dy", "0.35em") | |
.text(function(d) {return d.i + "," + d.j;}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment