2014-07-25 54 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