javascript - Drawing Hexagon on Canvas, testing mouseclick event vs Hexagon -
im drawing hexagon-based grid on canvas.
each hexagon object holds 6 points in x/y coordinates. each hexagon object holds x/y columns/row index.
var canvas = document.getelementbyid("can"); canvas.width = 200; canvas.height = 200; var ctx = canvas.getcontext("2d"); var grid = []; // array holds hex var globaloffset = 30 // not important, smoother display atm function point(x, y) { this.x = x; this.y = y; } function hex(x, y, size) { this.size = 20; this.x = x; this.y = y; this.points = []; this.id = []; this.create = function(x, y) { var offsetx = (size / 2 * x) * -1 var offsety = 0; if (x % 2 == 1) { offsety = math.sqrt(3) / 2 * this.size; } var center = new point( x * this.size * 2 + offsetx + globaloffset, y * math.sqrt(3) / 2 * this.size * 2 + offsety + globaloffset ) this.midpoint = center; this.id[0] = x; this.id[1] = y; (var = 0; < 6; i++) { var degree = 60 * i; var radian = math.pi / 180 * degree; var point = new point( center.x + size * math.cos(radian), center.y + size * math.sin(radian) ) this.points.push(point); } } this.create(x, y); } } //determine clicked canvas.addeventlistener("click", function(e) { var rect = canvas.getboundingclientrect(); var pos = { x: e.clientx - rect.left, y: e.clienty - rect.top } document.getelementbyid("pos").innerhtml = "click on: " + pos.x + " " + pos.y; }); // creating hexagons, setting center point, pushing them grid. function init() { (var = 0; < 5; i++) { (var j = 0; j < 4; j++) { var hex = new hex(i, j, 20); grid.push(hex) } } //for each hex in grid, draw hex (var hex in grid) { var item = grid[hex]; ctx.beginpath(); ctx.moveto(item.points[0].x, item.points[0].y); (var k = 1; k < item.points.length; k++) { ctx.lineto(item.points[k].x, item.points[k].y); } ctx.closepath(); ctx.stroke(); var text = item.id; ctx.fillstyle = "black"; ctx.filltext(text, item.midpoint.x - 7, item.midpoint.y - item.size / 2.2); }
when clicking on canvas want determine if clicked hex or not, , if did, hex (by column/row). math problem.
how can ?
fully working example here: http://codepen.io/anon/pen/rrmzky?editors=1111
if treat hexagon centres if centres of circles, clicked hexagon 1 centre closest click. (it should possible optimise without testing distance every possible cell).
to account incomplete coverage, assume there more (invisible) hexagons in additional ring surrounding visible ones.
if 1 of chosen, or if distance greater circle radius, click not on visible hexagon.
somewhat based on refactoring of own proposed code, , avoiding 2 loops since gain elimination of single sqrt
function:
grid.prototype.gethexat = function(pos) { var closest = null; var min = infinity; grid.hexes.foreach(function(hex) { var dx = hex.center.x - pos.x; var dy = hex.center.y - pos.y; var distance = math.sqrt(v.x * v.x + v.y * v.y); if (distance < hex.size && distance < min) { min = distance; closest = hex; } }); return closest; // may return null }
Comments
Post a Comment