将二维数组划分为曲面

时间:2017-05-29 17:50:29

标签: php arrays matrix

对于项目,需要根据每个平面的百分比将二维阵列布置到彼此成比例的平面中。 (我希望这是有道理的,否则见下面的例子)。在这个2D阵列中,第一个' level代表行和' second'级别,列。例如;

array(
    // row 1
    array(
        // items
        number1
        number2
        numberN
    ),
    // row 2
    array(
        // items..
    ),
    // row N
    array(
        // items..
    )
)

此阵列中的数字可以通过它们形成面板的方式添加/排列。面板一起形成一个网格。每个数字代表一个项目(对于这个问题是什么并不重要)。我自己想出了一个解决方案。 Click here for print of the 2D array (The groups are color coded.)

可以说,有三组(如下所列)。这些小组确实代表了上面介绍的小组。每组的百分比在0到100之间。飞机百分比的总和要求为百分之百。最大组数为7。示例组信息;

  • 第1组(A组):70%
  • 第2组(B组):20%
  • 第3组(图C):10%

同样,这种安排应该会产生一个带有(子)面板的大面板。 As shown in this schematic figure.

我想出了将最终结果分成4个角落的想法。每个角落都将按规则计算。这些角应该是镜像(水平和/或垂直),基于它的角落(左上角,右上角,左下角,右下角)。

规则清单;

  • 每行的项目数应相同
  • 完整网格的方面比例应为2比1.所以宽度是高度的两倍。
  • 行数基于总项目,因为方面已知。

经过几天的工作,我能够找到一个工作脚本。但是在某些情况下,这确实很奇怪(很奇怪,但并不像预期的那样)。见上面的当前解决方案。

所以,我的问题是;杠杆设计师如何做到这一点这是一个已知的问题,是否有解决方案(如算法)解决这种(某种)问题?我很长一段时间都在努力解决以下问题。在互联网上搜索,试图找到类似的问题。但我没有成功 我不是要求现成的解决方案。只是一个正确方向的指针将非常感激。

1 个答案:

答案 0 :(得分:0)

假设平面应具有与完整矩阵大致相同的“宽高比”,您可以使用此算法:

  • 计算应用于宽度和高度的系数的每个百分比,以获得在减去可用区域的百分比后将留下的确切区域。该系数是需要应用于该区域的系数的平方根(与百分比相关)。

  • 由于此系数通常为非整数,请检查舍入宽度和高度的方式会产生最接近所需区域的区域。

  • 对每个平面重复此操作。

以下是代码:

function createPlanes($width, $height, $groupPercentages) {
    $side = 0;
    $area = $width * $height;
    $planeWidth = $width;
    $planeHeight = $height;
    $sumPct = 0;
    $coefficient2 = 1;
    foreach ($groupPercentages as $i => $pct) {
        $plane = [
            "column" => floor(($width - $planeWidth) / 2),
            "row" => floor(($height - $planeHeight) / 2),
            "width" => $planeWidth,
            "height" => $planeHeight,
        ];
        $coefficient2 -= $pct / 100;
        $coefficient = sqrt($coefficient2);
        $planeArea = $coefficient2 * $area;
        $planeWidth = $coefficient * $width;
        $planeHeight = $coefficient * $height;
        // determine all possible combinations of rounding:
        $deltas = [
            abs(floor($planeWidth) * floor($planeHeight) - $planeArea),
            abs(floor($planeWidth) * min(ceil($planeHeight), $plane["height"]) - $planeArea),
            abs(min(ceil($planeWidth), $plane["width"])  * floor($planeHeight) - $planeArea),
            abs(min(ceil($planeWidth), $plane["width"]) * min(ceil($planeHeight), $plane["height"]) - $planeArea)
        ];
        // Choose the one that brings the area closest to the required area
        $choice = array_search(min($deltas), $deltas);
        $planeWidth = $choice & 2 ? ceil($planeWidth) : floor($planeWidth);        
        $planeHeight = $choice & 1 ? ceil($planeHeight) : floor($planeHeight);
        $newSumPct = ($area - $planeWidth * $planeHeight) / $area * 100;
        $plane["pct"] = $newSumPct - $sumPct;
        $sumPct = $newSumPct;
        $planes[] = $plane;
    }
    return $planes;
}

// Example call for a 2D array with 20 columns and 32 rows, and
// three percentages: 10%, 20%, 70%:
$planes = createPlanes(20, 32, [10, 20, 70]);

$planes变量将获取此内容:

array (
  array (
    'column' => 0,
    'row' => 0,
    'width' => 20,
    'height' => 32,
    'pct' => 10.9375,
  ),
  array (
    'column' => 0,
    'row' => 1,
    'width' => 19,
    'height' => 30,
    'pct' => 20,
  ),
  array (
    'column' => 1,
    'row' => 3,
    'width' => 17,
    'height' => 26,
    'pct' => 69.0625,
  ),
)

内部属性定义平面开始的位置(行,列),以及它的大小(高度,宽度),以及平面相对于总面积的实际百分比。

请注意,实际2D不需要是算法的一部分,因为它的值不会影响它。