Algorithm 网格布局算法

Algorithm 网格布局算法,algorithm,math,fill,Algorithm,Math,Fill,给定一个大小为wxh的矩形,并要求在该较大矩形内安装大小相同的n矩形,为那些最适合填充原始矩形的较小矩形选择大小dx和dy 主要的限制是所有数字必须是整数 我目前的(JS)算法如下: function pack(n, w, h) { var nx, ny; var dx = w, dy = h; // initally try one rectangle that fills the box while (true) { nx = ~~(w / dx

给定一个大小为
w
x
h
的矩形,并要求在该较大矩形内安装大小相同的
n
矩形,为那些最适合填充原始矩形的较小矩形选择大小
dx
dy

主要的限制是所有数字必须是整数

我目前的(JS)算法如下:

function pack(n, w, h) {

    var nx, ny;
    var dx = w, dy = h;  // initally try one rectangle that fills the box

    while (true) {
        nx = ~~(w / dx); // see how many times this fits in X
        ny = ~~(h / dy); // and in Y

        if (nx * ny >= n) break;   // they all fit!

        if (dx * h >= w * dy) {    // look at the aspect ratio
            dx = ~~(w / (nx + 1)); // try fitting more horizontally
        } else {
            dy = ~~(h / (ny + 1)); // or try more vertically
        }

        if (dx < 1 || dy < 1) {
            return;                // they can't fit
        }
    };

    return [nx, ny, dx, dy];
};
功能包(n、w、h){
var nx,纽约;
var dx=w,dy=h;//首先尝试填充方框的一个矩形
while(true){
nx=~(w/dx);//看看这在X中适合多少次
ny=~(h/dy);//在Y中
如果(nx*ny>=n)中断;//它们都适合!
如果(dx*h>=w*dy){//请查看纵横比
dx=~(w/(nx+1));//尝试更水平地拟合
}否则{
dy=~(h/(ny+1));//或者尝试更垂直的方向
}
if(dx<1 | | dy<1){
return;//它们不适合
}
};
返回[nx,ny,dx,dy];
};
有更好的算法吗

[注意:这不是家庭作业-我试图解决如何在画布上的矩阵中绘制“n”个项目的问题,但每个项目必须仅使用整像素]。

函数拾取(瓷砖、网格宽度、网格高度)
{
var max\u area=~~(网格宽度*网格高度/瓷砖);
对于(var面积=最大面积;面积>0;面积--)
{
var结果=[网格宽度*网格高度-面积*瓷砖];
除数_do(面积,
功能(瓷砖宽度)
{
var瓷砖高度=面积/瓷砖宽度;
如果(平铺宽度>网格宽度)返回true;
如果(平铺高度>网格高度)返回true;
var count\u HORINAL=~(网格宽度/平铺宽度);
变量计数垂直=~~(网格高度/平铺高度);
如果(水平计数*垂直计数<平铺)返回true;
结果:推([
瓷砖宽度,瓷砖高度,
水平计数,垂直计数
]);
});
如果(result.length>1)返回结果;
}
返回null;
}
函数除数_-do(x,f)
{
var历史=[1];
如果(f(1)==false)返回false;
//对于每个素因子
返回素数因子do(x,
函数(prime,primePower)
{
var len=历史长度;
对于(变量iHistory=0;iHistory
例如:

> pack(5, 12, 8);
[16, [2, 8, 6, 1], [4, 4, 3, 2]]
> pack(47,1024,768);
[16384, [64, 256, 16, 3], [128, 128, 8, 6], [256, 64, 4, 12], [512, 32, 2, 24]]
第一个示例产生两个等效结果:

  • 2x8瓷砖,一排6块
  • 4x4瓷砖,分两排,每排3块
在每种情况下,一个插槽未使用,总共有16个单元未使用

### ### ### ### ### . .    ####### ####### #######
### ### ### ### ###        ####### ####### #######
### ### ### ### ### . .    ####### ####### #######
### ### ### ### ###        ####### ####### #######
### ### ### ### ### . .    ####### ####### #######
### ### ### ### ###        ####### ####### #######
### ### ### ### ### . .    ####### ####### #######
### ### ### ### ###
### ### ### ### ### . .    ####### ####### .  .  .
### ### ### ### ###        ####### ####### 
### ### ### ### ### . .    ####### ####### .  .  .
### ### ### ### ###        ####### ####### 
### ### ### ### ### . .    ####### ####### .  .  .
### ### ### ### ###        ####### ####### 
### ### ### ### ### . .    ####### ####### .  .  .

看起来你基本上是在尝试计算,你可以使用有效的


首先,计算gwn=GCD(w,n)和ghn=GCD(h,n)。如果其中任何一个是n,那么就完成了-如果gwn=n,这意味着每个矩形可以是w/n乘以h像素。否则,只有当h可以被n/gwn整除或w可以被n/ghn整除时,才能拟合矩形。

这可能会有所帮助。这是一个非常类似的问题,但不完全相同。这可能会给你一些想法。同样,也可以对较小的矩形进行拟合“我必须受到一定的高宽比或诸如此类的限制吗?”@Chris,嗯,它们不应该是1像素宽乘以200像素高,例如…@Altinak:我希望有比这更具体的东西。;-)我不知道您的具体使用情况,但您可能会更好,不一定要选择最佳拟合,而是以某种方式限制比率dx/dy,这意味着您有一个更美观的结果,即使与使用所有像素但具有极端纵横比的东西相比,它浪费了一个像素…@chris美学上,我是aiming表示“近似”的纵横比与原始网格的情况相同。听起来你在描述一个精确的拟合,在任何一个轴上都没有剩余的多余像素?阿尔尼塔克:你是对的,我必须考虑不精确的情况。我使用因子分解重写了它。它现在尝试越来越小的区域,直到得到结果。现在速度快了很多,但我没有知道它是否变得更好了。