javascriptjquerymathcanvasjcanvas

How to calculate and place circles on an rect area?


I'm trying to draw some charts on a Canvas Area. My Problem is following...

I have 1-4 (or more) circles to draw. The canvas size is like 500 x 400 px. How can i now calculate the max Radius of each circle to place all on this canvas and get the position (center x/y) of each circle? So each circle could be optimal placed on the area with some margin to each other?

here some example screens to show you what i mean...

placing four circles Place the circles like a table

thanks a lot!


Solution

  • To calculate the maximum radius you can use

        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
    }
    

    Calculate the margins for X and 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
        }
    

    After that you can calculate the centers:

    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;
    }
    

    Hope this helps.

    UPDATE: It is still incomplete but it may work in this particular example: http://jsfiddle.net/dhM96/4/