PHP & Geometry - 如何优雅地计算常见的对象方向(长/宽/高)?

PHP & Geometry - how to elegantly compute common object orientation (length/width/height)?

提问人:DRT 提问时间:12/14/2015 最后编辑:DRT 更新时间:1/6/2016 访问量:540

问:

我试图让 PHP 调整一些数组值,以便在通过功能传递的对象的所有实例中,它将比较这些数组值的长度、宽度和高度,并尽可能地对齐它们。

想象一下,3 个香烟盒。它们的大小、形状和体积完全相同,但一个是站立的,一个是平躺的,另一个是短的。

然后,想象第四个香烟盒。它的长度和宽度与其他数据包相同,但它在容器内有更多的香烟包,因此使其高度(或宽度/长度取决于用户输入)到其他数据包。

该函数仍应尝试将数据包定向到数组中的原始数据包中。

Visual Example

香烟纸盒的例子并不是真正的应用。我有一堆箱子,需要分类成共同的排列方式,以便可以堆叠。它应该足够智能,可以在至少 2 次测量中计算或忽略与类似大小的物体相关的任何其他形状。如果所有 3 个尺寸相同但方向不同,则应在适用的情况下纠正它们,如果无法比较,则应打破循环。

我已经模拟了一些示例PHP代码,这些代码应该会给出一些很好的测试用例和预期结果。

任何帮助都非常感谢,我已经尝试了很多array_diffs和array_intersects的组合,但似乎在所有情况下都缺少一个解决方案。

更新:

我想我开始意识到有 3 类计算。实现后,它们可能会被重构。

如果您考虑第一个不会旋转的对象,那么它有三种可能性,我可能需要为每个对象编写单独的逻辑,以应用于它下面的每个循环。也许案例 1 和案例 2 的逻辑会有些相似......

  1. AxBxC 所有不同的尺寸,比较
  2. AxBxB 2 相似尺寸,比较
  3. AxAxA 所有相同的尺寸,无旋转

所以它至少消除了一些因素......仍在努力......

<?php

$params['object'] = array();
/* START TEST 1 */
$params['object'][] = array(    'height'=>'30',
                                'width'=>'10',
                                'length'=>'20');
$params['object'][] = array(    'height'=>'20',
                                'width'=>'30',
                                'length'=>'30');
/* END TEST 1 */
/* START TEST 2 
$params['object'][] = array(    'height'=>'30',
                                'width'=>'30',
                                'length'=>'20');
$params['object'][] = array(    'height'=>'30',
                                'width'=>'20',
                                'length'=>'30');
/* END TEST 2 */
/* START TEST 3 
$params['object'][] = array(    'height'=>'30',
                                'width'=>'16',
                                'length'=>'14');
$params['object'][] = array(    'height'=>'30',
                                'width'=>'20',
                                'length'=>'30');
/* END TEST 3 */

echo '<PRE>';
echo 'INPUT<BR>';
print_r($params['object']);

//Check for common orientations
/* PLEASE KEEP BETWEEN HERE --- */
$rotated = array();
foreach($params['object'] as $on=>$outer){
    if(in_array($on,$rotated)){ continue; }
    $rotated[$on] = $on;
    if($oo['width']==$oo['length'] && $oo['length']==$oo['height']){ continue; }
    $oo = array('width'=>$outer['width'],
                'length'=>$outer['length'],
                'height'=>$outer['height']);
    foreach($params['object'] as $in=>$inner){
        if(in_array($in,$rotated)){ continue; }
        if($in==$on){ continue; }
        $ii = array('width'=>$inner['width'],
                    'length'=>$inner['length'],
                    'height'=>$inner['height']);
        /* --- TO HERE */

        //DETERMINE HOW TO ROTATE THESE???
        //IF ROTATED, MARK AS ROTATED[$in] TO PREVENT FURTHER ROTATIONS TO OCCUR TO THIS ITEM

        $rotated[$in] = $in;
    }
}

echo 'OUTPUT<BR>';
print_r($params['object']);

/* TEST 1 OUTPUT SHOULD BE - ALIGNED SAME ORIENTATION, BUT EACH OBJ IS DIF WIDTH
- same logic should work if any of the H/W/L are in different orders but values consistant in any 2 pairs
Array
(
    [0] => Array
        (
            [height] => 30
            [width] => 10
            [length] => 20
        )

    [1] => Array
        (
            [height] => 30
            [width] => 30
            [length] => 20
        )

)
*/
/* TEST 2 OUTPUT SHOULD BE - SAME VALUES, SO ALIGN COMPLETELY
- same logic should work if any of the H/W/L are in different orders
Array
(
    [0] => Array
        (
            [height] => 30
            [width] => 30
            [length] => 20
        )

    [1] => Array
        (
            [height] => 30
            [width] => 30
            [length] => 20
        )

)
*/
/* TEST 3 OUTPUT SHOULD BE - NO CHANGE BECAUSE LESS THAN 2 COMPATIBLE MEASUREMENTS, NO ADD TO $rotation[$in]
Array
(
    [0] => Array
        (
            [height] => 30
            [width] => 16
            [length] => 14
        )

    [1] => Array
        (
            [height] => 30
            [width] => 20
            [length] => 30
        )

)
*/

?>
PHP MySQL 数组 对象 几何

评论

0赞 Darragh Enright 12/14/2015
这是一个有趣的问题,尽管我不得不承认这张图让我有些困惑,因为它似乎与您对所有香烟盒位于不同侧面的描述不符。话又说回来,现在是凌晨一点:D
0赞 DRT 12/14/2015
我想我可以找到 3 个不同位置的纸箱的图像,但我试图给它们贴上标签以证明它们的方向(W / L / H)。也许对你来说只是凌晨 1 点......哈哈。也许我应该更新那张照片。显然,我的 Photoshop 技能是精英。:P
0赞 Darragh Enright 12/14/2015
都很好。如果您通过匹配尺寸来堆叠项目,您是否将这些项目堆叠在某种父容器的边界内?
0赞 DRT 12/14/2015
我是,但这已经是计算好的,超出了我需要回答的问题的范围。我只需要优雅地对常见方向进行排序。
0赞 DRT 12/14/2015
更新了原始图像以使其更清晰,谢谢 Darragh。

答: 暂无答案