用六边形填充圆 [英] filling circle with hexagons

查看:229
本文介绍了用六边形填充圆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到一种尽可能多的将六边形放在一个圆圈内的方法。到目前为止,我获得的最好结果是通过从中心向外以圆形生成六边形。



但我认为我的计算得到最大六边形圆圈是错误的,尤其是我使用 Math .ceil() Math.Floor 函数可以向下舍入一些值。



当使用 Math.ceil()时,六边形有时会与圆形重叠。

另一方面,当使用 Math.floor()时,它有时在最后一圈六边形和圆形边界之间留下太多空间。



  var c_el = document.getElementById(myCanvas); var ctx = c_el.getContext(2d); var canvas_width = c_el。 clientWidth; var canvas_height = c_el.clientHeight; var PI = Math.PI; var PI2 = PI * 2; var hexCircle = {r:110,/// radius pos:{x:(canvas_width / 2),y:(canvas_height / 2)}}; var hexagon = {r:20,pos:{x:0,y:0},space:1}; drawHexCircle(hexCircle,hexagon);函数drawHexCircle(hc,hex){drawCircle(hc) ; var hcr = Math.ceil(Math.sqrt(3)*(hc.r / 2)); var hr = Math.ceil((Math.sqrt(3)*(hex.r / 2)))+ hexagon.space; // hexRadius var circles = Math.ceil((hcr / hr)/ 2); drawHex(hc.pos.x,hc.pos.y,hex.r); (var j = 0; j <6; j ++){var currentX = hc.pos.x + Math.cos(j * PI2 / 6)*小时* 2 * I; var currentY = hc.pos.y + Math.sin(j * PI2 / 6)* hr * 2 * i; drawHex(currentX,currentY,hex.r); (var k = 1; k  

< canvas id = myCanvaswidth =350height =350style =border:1px solid#d3d3d3;>

p>

解决方案

如果六边形上的所有点都在圆内,则六边形在圆内。我不认为比做距离计算更简单。



我不确定如何选择最佳填充点,(但这里有一个js片段验证中间并不总是这样)。这可能是因为当你说六边形圆时,你的意思是六边形由六边形制成,在这种情况下,片段证明什么都没有:)

我将六边形制成了2 / 11ths圆的半径并将它们间隔5%的边长。

10}; var circle = {x:100,y:100,r:100}; var spacing = 1.05; var SQRT_3 = Math.sqrt(3); var hexagon_offsets = [{x:1/2,y:-SQRT_3 / 2},{x:1,y:0},{x:1/2,y:SQRT_3 / 2},{x:-1/2,y:SQRT_3 / 2},{x:-1,y :0},{x:-1/2,y:-SQRT_3 / 2}]; var bs = document.body.style; var ds = document.documentElement.style; bs.height = bs.width = ds.height = ds.width =100%; bs.border = bs.margin = bs.padding = 0; var c = document.createElement(canvas); c.style.display =block; c.addEventListener mousemove,follow,false); document.body.appendChild(c); var ctx = c.get Context(2d); window.addEventListener(resize,redraw); redraw(); function follow(e){hex.x = e.clientX; hex.y = e.clientY; redraw();}函数drawCircle(){ctx.strokeStyle =black; ctx.beginPath(); ctx.arc(circle.x,circle.y,circle.r,0,2 * Math.PI,true); ctx.closePath(); ctx.stroke();} function is_in_circle(p){return Math.pow(p.x - circle.x,2)+ Math.pow(p.y - circle.y,2) Math.pow(circle.r,2);} function drawLine(a,b){var within = is_in_circle(a)&& is_in_circle(b)中; ctx.strokeStyle =内? 绿色:红色; ctx.beginPath(); ctx.moveTo(a.x,a.y); ctx.lineTo(b.x,b.y); ctx.closePath(); ctx.stroke(); return within;}函数drawShape(shape){var within = true;对于(var i = 0; i< shape.length; i ++){within = drawLine(shape [i%shape.length],shape [(i + 1)%shape.length])&&中; } if(!within)return false; ctx.fillStyle =绿色; ctx.beginPath(); ctx.moveTo(shape [0] .x,shape [0] .y); for(var i = 1; i <= shape.length; i ++){ctx.lineTo(shape [i%shape.length] .x,shape [i%shape.length] .y); } ctx.closePath(); ctx.fill();返回true;}函数calculate_hexagon(x,y,r){return hexagon_offsets.map(function(offset){return {x:x + r * offset.x,y:y + r * offset.y};})}函数drawHexGrid(){var hex_count = 0; var grid_space = calculate_hexagon(0,0,hex.r * spacing); var y = hex.y; var x = hex.x;而(y> 0){y + = grid_space [0] .y * 3; x + = grid_space [0] .x * 3; } while(y

b $ b

I'm trying to find a way to put as much hexagons in a circle as possible. So far the best result I have obtained is by generating hexagons from the center outward in a circular shape.

But I think my calculation to get the maximum hexagon circles is wrong, especially the part where I use the Math.ceil() and Math.Floor functions to round down/up some values.

When using Math.ceil(), hexagons are sometimes overlapping the circle.
When using Math.floor() on the other hand , it sometimes leaves too much space between the last circle of hexagons and the circle's border.

var c_el = document.getElementById("myCanvas");
var ctx = c_el.getContext("2d");

var canvas_width = c_el.clientWidth;
var canvas_height = c_el.clientHeight;

var PI=Math.PI;
var PI2=PI*2;

var hexCircle = {
	r: 110, /// radius 
	pos: {
		x: (canvas_width / 2),
		y: (canvas_height / 2)
	}
};

var hexagon = {
	r: 20,
	pos:{
		x: 0,
		y: 0
	},
	space: 1
};

drawHexCircle( hexCircle, hexagon );
function drawHexCircle(hc, hex ) {
	drawCircle(hc);
	var hcr = Math.ceil( Math.sqrt(3) * (hc.r / 2) ); 
    var hr =  Math.ceil( ( Math.sqrt(3) * (hex.r / 2) ) ) + hexagon.space; // hexRadius
	var circles =  Math.ceil( ( hcr / hr ) / 2 );
    drawHex( hc.pos.x , hc.pos.y, hex.r ); //center hex ///
	for (var i = 1; i<=circles; i++) {
		for (var j = 0; j<6; j++) {
			var currentX = hc.pos.x+Math.cos(j*PI2/6)*hr*2*i;
			var currentY = hc.pos.y+Math.sin(j*PI2/6)*hr*2*i;
			drawHex( currentX,currentY, hex.r );
			for (var k = 1; k<i; k++) {
				var newX = currentX + Math.cos((j*PI2/6+PI2/3))*hr*2*k;
				var newY = currentY +  Math.sin((j*PI2/6+PI2/3))*hr*2*k;
				drawHex( newX,newY, hex.r );
			}
		}
	}
}

function drawHex(x, y, r){
    ctx.beginPath();
    ctx.moveTo(x,y-r);
    for (var i = 0; i<=6; i++) {
        ctx.lineTo(x+Math.cos((i*PI2/6-PI2/4))*r,y+Math.sin((i*PI2/6-PI2/4))*r);
    }
    ctx.closePath();
    ctx.stroke();
}

function drawCircle( circle ){
	ctx.beginPath();
	ctx.arc(circle.pos.x, circle.pos.y, circle.r, 0, 2 * Math.PI);
	ctx.closePath();
	ctx.stroke();
}

<canvas id="myCanvas" width="350" height="350" style="border:1px solid #d3d3d3;">

解决方案

If all the points on the hexagon are within the circle, the hexagon is within the circle. I don't think there's a simpler way than doing the distance calculation.

I'm not sure how to select the optimal fill point, (but here's a js snippet proving that the middle isn't always it). It's possible that when you say "hexagon circle" you mean hexagon made out of hexagons, in which case the snippet proves nothing :)

I made the hexagon sides 2/11ths the radius of the circle and spaced them by 5% the side length.

var hex = {x:0, y:0, r:10};
var circle = {x:100, y:100, r:100};
var spacing = 1.05;
var SQRT_3 = Math.sqrt(3);
var hexagon_offsets = [
  {x: 1/2, y: -SQRT_3 / 2},
  {x: 1, y: 0},
  {x: 1/2, y: SQRT_3 / 2},
  {x: -1/2, y: SQRT_3 / 2},
  {x: -1, y: 0},
  {x: -1/2, y: -SQRT_3 / 2}
];


var bs = document.body.style;
var ds = document.documentElement.style;
bs.height = bs.width = ds.height = ds.width = "100%";
bs.border = bs.margin = bs.padding = 0;
var c = document.createElement("canvas");
c.style.display = "block";
c.addEventListener("mousemove", follow, false);
document.body.appendChild(c);
var ctx = c.getContext("2d");
window.addEventListener("resize", redraw);
redraw();


function follow(e) {
  hex.x = e.clientX;
  hex.y = e.clientY;
  redraw();
}
function drawCircle() {
  ctx.strokeStyle = "black";
  ctx.beginPath();
  ctx.arc(circle.x, circle.y, circle.r, 0, 2 * Math.PI, true);
  ctx.closePath();
  ctx.stroke();
}
function is_in_circle(p) {
  return Math.pow(p.x - circle.x, 2) + Math.pow(p.y - circle.y, 2) < Math.pow(circle.r, 2);
}
function drawLine(a, b) {
  var within = is_in_circle(a) && is_in_circle(b);
  ctx.strokeStyle = within ? "green": "red";
  ctx.beginPath();
  ctx.moveTo(a.x, a.y);
  ctx.lineTo(b.x, b.y);
  ctx.closePath();
  ctx.stroke();
  return within;
}
function drawShape(shape) {
  var within = true;
  for (var i = 0; i < shape.length; i++) {
    within = drawLine(shape[i % shape.length], shape[(i + 1) % shape.length]) && within;
  }
  if (!within) return false;
  ctx.fillStyle = "green";
  ctx.beginPath();
  ctx.moveTo(shape[0].x, shape[0].y);
  for (var i = 1; i <= shape.length; i++) {
    ctx.lineTo(shape[i % shape.length].x, shape[i % shape.length].y);
  }
  ctx.closePath();
  ctx.fill();
  return true;
}
function calculate_hexagon(x, y, r) {
  return hexagon_offsets.map(function (offset) {
    return {x: x + r * offset.x, y: y + r * offset.y};
  })
}
function drawHexGrid() {
  var hex_count = 0;
  var grid_space = calculate_hexagon(0, 0, hex.r * spacing);
  var y = hex.y;
  var x = hex.x;
  while (y > 0) {
    y += grid_space[0].y * 3;
    x += grid_space[0].x * 3;
  }
  while (y < c.height) {
    x %= grid_space[1].x * 3;
    while (x < c.width) {
      var hexagon = calculate_hexagon(x, y, hex.r);
      if (drawShape(hexagon)) hex_count++;
      x += 3 * grid_space[1].x;
    }
    y += grid_space[3].y;
    x += grid_space[3].x;
    x += 2 * grid_space[1].x;
  }
  return hex_count;
}

function redraw() {
  c.width = window.innerWidth;
  c.height = window.innerHeight;
  circle.x = c.width / 2;
  circle.y = c.height / 2;
  circle.r = Math.min(circle.x, circle.y) * 0.9;
  hex.r = circle.r * (20 / 110);
  ctx.clearRect(0, 0, c.width, c.height);
  var hex_count = drawHexGrid();
  drawCircle();
  ctx.fillStyle = "rgb(0, 0, 50)";
  ctx.font = "40px serif";
  ctx.fillText(hex_count + " hexes within circle", 20, 40);
}

这篇关于用六边形填充圆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆