【发布时间】:2014-09-16 23:54:42
【问题描述】:
我正在尝试在画布区域上绘制一些图表。我的问题是...
我要画 1-4 个(或更多)圆圈。画布大小为 500 x 400 像素。我现在如何计算每个圆的最大半径以将所有内容放在此画布上并获取每个圆的位置(中心 x/y)?那么每个圆圈可以最佳地放置在彼此之间有一定边距的区域上吗?
这里有一些示例屏幕向您展示我的意思...
非常感谢!
【问题讨论】:
标签: javascript jquery math canvas jcanvas
我正在尝试在画布区域上绘制一些图表。我的问题是...
我要画 1-4 个(或更多)圆圈。画布大小为 500 x 400 像素。我现在如何计算每个圆的最大半径以将所有内容放在此画布上并获取每个圆的位置(中心 x/y)?那么每个圆圈可以最佳地放置在彼此之间有一定边距的区域上吗?
这里有一些示例屏幕向您展示我的意思...
非常感谢!
【问题讨论】:
标签: javascript jquery math canvas jcanvas
您所询问的Knapsack problem 很难解决。在您的情况下,最好的方法是使用给定的表,例如 http://www.packomania.com。如果可以,请将自己限制在一个正方形内。
【讨论】:
计算可以使用的最大半径
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/
【讨论】:
您没有提供足够的展示位置限制。
无论如何,假设沿矩形边缘有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。
【讨论】: