Skip to content

Instantly share code, notes, and snippets.

@Thanaporn-sk
Created March 9, 2017 03:58
Show Gist options
  • Save Thanaporn-sk/831c438ae68fbcaa04e2b654a8559a84 to your computer and use it in GitHub Desktop.
Save Thanaporn-sk/831c438ae68fbcaa04e2b654a8559a84 to your computer and use it in GitHub Desktop.
Generating hex grid positions
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<script>
console.clear()
var SQRT_3_2 = Math.sqrt(3)/2
var SCALE = 10
var toScreen = function(cube) {
var q = cube[0]
var r = cube[1]
var s = cube[2]
return {
x: SCALE * (r-q) * SQRT_3_2,
y: SCALE * (0.5*(r+q) - s)
}
}
// Feel free to change or delete any of the code you see in this editor!
var svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500)
var g = svg.append('g')
.attr('transform', 'translate(480, 250)')
var hexPositionFactory = function() {
let i = 0
let ring = 0
let currentPosition = [0, 0, 0]
let currentDirection = 0
let stepsInCurrentDirection = 0
let directions = [
[+1, -1, 0], [+1, 0, -1], [0, +1, -1],
[-1, +1, 0], [-1, 0, +1], [0, -1, +1]
]
let move = function(cur, dir) {
return [cur[0] + dir[0], cur[1] + dir[1], cur[2] + dir[2]]
}
return function() {
if (i === 0) {
i += 1
ring = 1
currentPosition = [0, 0, 0]
return currentPosition
}
let absoluteSum = currentPosition.reduce((c, p) => {
return Math.abs(p) + Math.abs(c)
}, 0)
if (absoluteSum / 2 < ring) {
stepsInCurrentDirection = 1
currentPosition = [-ring, 0, ring]
} else {
currentPosition = move(currentPosition, directions[currentDirection])
if (stepsInCurrentDirection >= ring) {
currentDirection = currentDirection + 1
if (currentDirection > directions.length - 1) {
ring += 1
currentDirection = 0
currentPosition = [-ring, 0, ring]
}
stepsInCurrentDirection = 1
} else {
stepsInCurrentDirection += 1
}
}
i += 1
return currentPosition.slice(0)
}
}
let mouseDistance = 0
svg
.on("mousemove", function(e) {
let m = d3.mouse(this)
let dx = 480 - m[0]
let dy = 250 - m[1]
mouseDistance = Math.sqrt(dx * dx + dy * dy)
})
let paint = function() {
let hexPosition = hexPositionFactory()
let numberOfCircles = Math.floor(mouseDistance)
let coordinates = d3.range(numberOfCircles).map((i) => {
return hexPosition()
}).map((cube, i) => {
return {
key: i,
cube: cube,
screen: toScreen(cube)
}
})
let points = g.selectAll('circle')
.data(coordinates, function(d) { return d.key })
points
.enter()
.append('circle')
.attr('r', 6)
.merge(points)
.attr('fill', function(d) {
let r = d.cube[0] * 5 + 150
let g = d.cube[1] * 5 + 150
let b = d.cube[2] * 5 + 150
return 'rgb(' + r + ', ' + g + ', ' + b + ')'
})
.attr('cx', function(d) {
return d.screen.x
})
.attr('cy', function(d) {
return d.screen.y
})
points.exit().remove()
window.requestAnimationFrame(paint)
}
window.requestAnimationFrame(paint)
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment