Pack in small circles in a larger circle

I am trying to figure out a way to pack smaller circles into larger ones, but for some reason the smaller circles are not aligned correctly.

I believe that the calculation of the situation, which is probably missing.

Please see the code for more details:

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 circle1 = {
	r: 50, /// radius 
	pos: {
		x: (canvas_width / 2),
		y: (canvas_height / 2)
	}
}

var circle2 = {
	r: 5,
	pos:{}
}

var c2h = circle2.r * 2; /// circle height ////
var c2w = c2h; //// circle width /////

var c1h = circle1.r * 2; /// circle height ////
var c1w = c1h; //// circle width /////

var max_circles2_H = c1h / c2h; 

var r = circle1.r;
var d = circle1.r - 2;  //// segement distance from center ////

drawCircle( circle1 );
for(var col = 1; col < max_circles2_H; col++){
	var d = circle1.r - ( col * c2h); /// distance from center to segment ///
	var c = 2 * (Math.sqrt((r*r) - (d * d))); //// circle chord length
	var max_circles2_W = c / c2w;
	for(var row = 1; row < max_circles2_W; row++){
		circle2.pos.x = (row * c2w) + (circle1.pos.x - circle1.r);
		circle2.pos.y = (col * c2h) + (circle1.pos.y - circle1.r);
		drawCircle(circle2);
	}
}


function drawCircle( circle ){
	ctx.beginPath();
	ctx.arc(circle.pos.x, circle.pos.y, circle.r, 0, 2 * Math.PI);
	ctx.stroke();
}
<canvas id="myCanvas" width="300" height="150">
Run codeHide result

Any help is appreciated.

+4
source share
1 answer

This is close, but you need to adjust a bit. You can see where x_offset is calculated, and try different maths to tighten it.

update Added by Math.ceil for max_circles2_W and seems to be suitable.

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 circle1 = {
	r: 50, /// radius 
	pos: {
		x: (canvas_width / 2),
		y: (canvas_height / 2)
	}
}

var circle2 = {
	r: 5,
	pos:{}
}

var c2h = circle2.r * 2; /// circle height ////
var c2w = c2h; //// circle width /////

var c1h = circle1.r * 2; /// circle height ////
var c1w = c1h; //// circle width /////

var max_circles2_H = c1h / c2h; 

var r = circle1.r;
var d = circle1.r - 2;  //// segement distance from center ////

drawCircle( circle1 );
for(var col = 1; col < max_circles2_H; col++){
	var d = circle1.r - ( col * c2h); /// distance from center to segment ///
	var c = 2 * (Math.sqrt((r*r) - (d * d))); //// circle chord length
	var max_circles2_W = Math.ceil(c / c2w);
  
    // CALCULATE OFFSET HERE
    var x_offset = Math.floor((c1w - (max_circles2_W * c2w)) / 2);
  
	for(var row = 1; row < max_circles2_W; row++){
		circle2.pos.x = (row * c2w) + (circle1.pos.x - circle1.r) + x_offset;
		circle2.pos.y = (col * c2h) + (circle1.pos.y - circle1.r);
        ctx.fillText(row, circle2.pos.x-3, circle2.pos.y+4);
		drawCircle(circle2);
	}
}


function drawCircle( circle ){
	ctx.beginPath();
	ctx.arc(circle.pos.x, circle.pos.y, circle.r, 0, 2 * Math.PI);
	ctx.stroke();
}
<canvas id="myCanvas" width="300" height="150">
Run codeHide result
+2
source

Source: https://habr.com/ru/post/1630081/


All Articles