我正试图在画布区域绘制一些图表。我的问题如下...如何计算并在矩形区域上放置圆圈?
我有1-4(或更多)圈画。画布大小像500 x 400像素。我现在如何计算每个圆的最大半径以将所有这些画布放在这个画布上并获取每个圆的位置(中心x/y)?那么每个圈子都可以优化放置在相互之间有一定边距的区域?
这里一些示例屏幕来展示一下我的意思是......
非常感谢!
我正试图在画布区域绘制一些图表。我的问题如下...如何计算并在矩形区域上放置圆圈?
我有1-4(或更多)圈画。画布大小像500 x 400像素。我现在如何计算每个圆的最大半径以将所有这些画布放在这个画布上并获取每个圆的位置(中心x/y)?那么每个圈子都可以优化放置在相互之间有一定边距的区域?
这里一些示例屏幕来展示一下我的意思是......
非常感谢!
要计算最大半径可以使用
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/
你问的Knapsack problem很难解决。在你的情况最好的办法是使用给定的表,如http://www.packomania.com。如果可以的话,限制自己到广场。
你没有给够你放置约束。
无论如何,假设沿着矩形边缘F
像素和圆圈之间f
的自由空间,对X
最大半径是Rx = (Width - 2 F - (Nx-1) f)/2
和Y
,R 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
。
看起来很有趣,但我不知道如何修改它。我尝试了下面的方法,但是它画了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
把它放在小提琴上:http://jsfiddle.net/hn7u7/ – HR123
@ HR123对不起,这个答案是不完整的,回答你的问题比我想象的更复杂。我创建了一个可以用作参考的jsfiddle:http://jsfiddle.net/hn7u7/3/。如果这对你有用,我会更新我的答案。 – lexmihaylov