2014-07-25 55 views
2

我正试图在画布区域绘制一些图表。我的问题如下...如何计算并在矩形区域上放置圆圈?

我有1-4(或更多)圈画。画布大小像500 x 400像素。我现在如何计算每个圆的最大半径以将所有这些画布放在这个画布上并获取每个圆的位置(中心x/y)?那么每个圈子都可以优化放置在相互之间有一定边距的区域?

这里一些示例屏幕来展示一下我的意思是......

placing four circles Place the circles like a table

非常感谢!

回答

2

要计算最大半径可以使用

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 
} 

计算X和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 
    } 

之后,你可以计算出中心:

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

希望这有助于。

更新:它仍然是不完整的,但它可能在这个特殊的例子工作:http://jsfiddle.net/dhM96/4/

+0

看起来很有趣,但我不知道如何修改它。我尝试了下面的方法,但是它画了6个圈子,大到半径和错误的位置。 var numberOfSections = data.length,//当前:4 \t \t \t R = Math。sqrt((cWidth * cHeight)/ numberOfSections)/ 2, \t \t \t centers = []; \t \t \t 为\t(VAR X = R,Y = R; X + = 2 * R){ \t \t \t如果(X> = cWidth){ \t \t \t \t X = R; \t \t \t \t y + = R; \t \t \t \t if(y> = cHeight)break; \t \t} \t \t \t canvas.drawArc({ \t \t \t \t fromCenter:真, \t \t \t \t的StrokeStyle:的StrokeStyle, \t \t \t \t strokeWidth:strokeWidth, \t \t \t \t开始:0, \t \t \t \t端:360, \t \t \t \t半径:R, \t \t \t \t X:X, \t \t \t \tÿ:Y \t \t \t}); \t \t} – HR123

+0

把它放在小提琴上:http://jsfiddle.net/hn7u7/ – HR123

+0

@ HR123对不起,这个答案是不完整的,回答你的问题比我想象的更复杂。我创建了一个可以用作参考的jsfiddle:http://jsfiddle.net/hn7u7/3/。如果这对你有用,我会更新我的答案。 – lexmihaylov

-1

你问的Knapsack problem很难解决。在你的情况最好的办法是使用给定的表,如http://www.packomania.com。如果可以的话,限制自己到广场。

+0

感谢您的快速回答。多数民众赞成我认为复杂。也许上面的新图像更有帮助。我想把它们放在桌子上。 – HR123

+0

这个问题与knapstack无关。这是一个包装问题! http://en.wikipedia.org/wiki/Packing_problem。 OP所查询的问题的实例很简单。 –

+0

我回答了原来的问题。只有在编辑之后,它才会变得微不足道。 – sina72

1

你没有给够你放置约束。

无论如何,假设沿着矩形边缘F像素和圆圈之间f的自由空间,对X最大半径是Rx = (Width - 2 F - (Nx-1) f)/2YR y = (Height - 2F - (Ny-1) f)/2。 (Nx水平放置,垂直放置Ny。)取两个中最小的一个。

该中心将在(F + (2 Rx + f) Ix + Rx, F + (2 Ry + f) Iy + Ry),0 <= Ix < Nx,0 <= Iy < Ny