Como calcular e colocar círculos em uma área rect?

Estou a tentar desenhar alguns gráficos numa área de tela. O meu problema é seguir...

Tenho 1-4 (ou mais) círculos para desenhar. O tamanho da tela é de 500 x 400 px. Como posso agora calcular o raio máximo de cada círculo para colocar tudo nesta área de desenho e obter a posição (centro x/y) de cada círculo? Então, cada círculo poderia ser o melhor colocado na área com alguma margem um para o outro?

Veja alguns exemplos para mostrar o que quero dizer...

placing four circlesPlace the circles like a table

Obrigado. lot!

Author: HR123, 2014-07-25

3 answers

Para calcular o raio máximo que pode usar

    var numberOfSections = 4;
    var width = 500;
    var height = 400;
    var R = Math.sqrt((width * height) / numberOfSections) / 2

    var MX = Math.round(width / (R * 2)); // max amount of squares that can fit on the width
    var MY = Math.round(height / (R * 2)); // max amount of squares that can fit on the height

var skipLast = 0;
var numOfCalculatedCircles = MX*MY;
if(numOfCalculatedCircles != numberOfSections) {

    if(numOfCalculatedCircles < numberOfSections) {
        console.log('numOfCalculatedCircles',numOfCalculatedCircles);
        MX = MX + Math.ceil((numberOfSections - numOfCalculatedCircles)/MY);
        if(MX*MY != numberOfSections) {
            skipLast = Math.abs(MX*MY - numberOfSections);
        }
    } else {
        skipLast = numOfCalculatedCircles - numberOfSections;;
    }

    console.log('MX*MY',MX*MY);
}
// recalculate the radius for X
if (R * 2 * MX > width) {
    R = (width/2) / MX;
}

// recalculate the radius for Y
if (R * 2 * MY > height) {
    R = (height/2) / MY
}

Calcule as margens para X e Y:

    var circlesWidth = R * 2 * MX;
    var circlesHeight = R * 2 * MY;

    var marginX = 0;
    var marginY = 0;
    if (circlesWidth < width) {
        marginX = (width - circlesWidth) / 2
    }
    if (circlesHeight < height) {
        marginY = (height - circlesHeight) / 2
    }
Depois disso, podes calcular os centros.
var RY = marginY + R;
var radiusPadding = 10;

for (var i = 0; i < MY; i++) {
    var RX = marginX + R;
    for (var j = 0; j < MX; j++) {
        if(i === MY - 1) {
          if(j === MX - skipLast) {
            break;
          }
        }
        canvas.drawArc({
            fromCenter: true,
            strokeStyle: 'red',
            strokeWidth: 1,
            start: 0,
            end: 360,
            radius: R - radiusPadding,
            x: RX,
            y: RY
        });

        RX += 2 * R;
    }

    RY += 2 * R;
}
Espero que isto ajude.

Actualização: ainda está incompleta, mas pode funcionar neste exemplo em particular: http://jsfiddle.net/dhM96/4/

 2
Author: lexmihaylov, 2014-07-25 14:43:22

Não estás a dar o suficiente das tuas restrições de colocação.

De qualquer forma, assumindo um espaço livre de F pixels ao longo dos bordos do rectângulo e f entre os círculos, o raio máximo em X é Rx = (Width - 2 F - (Nx-1) f) / 2 e em Y, R y = (Height - 2F - (Ny-1) f) / 2. (Nx círculos horizontalmente, Ny verticalmente.) Take the smallest of the two.

Os centros estarão em (F + (2 Rx + f) Ix + Rx, F + (2 Ry + f) Iy + Ry), 0 <= Ix < Nx, 0 <= Iy < Ny.
 1
Author: Yves Daoust, 2014-07-25 12:32:38

O problema da mochila que estás a perguntar é difícil de resolver. A melhor abordagem no seu caso é usar uma dada tabela, como http://www.packomania.com. SE PUDERES, limita-te a um quadrado.

 -1
Author: sina72, 2014-07-25 07:53:55