我正在编写一个应用程序,它将N维轴对齐的边界框细分为较小的N维边界框,我需要一个能够做到这一点的算法。
例如:
在1维中,“边界框”仅为长度
例如{Min = 0,Max = 100}
这将细分为
{Min = 0,Max = 50}且{Min = 50,Max = 100}
在2维中,“边界框”是正方形
例如{Min = [0,0],Max = [100,100]}
将分为
{Min = [0,0],Max = [50,50]}
{Min = [0,50],Max = [50,100]}
{Min = [50,0],Max = [100,50]}
{Min = [50,50],Max = [100,100]}
依此类推,我需要的只是对算法的描述,语言并不特别重要,因为一旦我知道如何去做,我就可以把它翻译成选择的语言(在这种情况下是C#)
编辑::回答评论中的问题:
答案 0 :(得分:1)
将其分解为两个问题:迭代“最小”点的网格,并为最小点构建一个小方框。
对于您的第二种情况,{[0,0],[100,100]},deltaX = 50,deltaY = 50。网格是
[0, 0] [0, 50] [50, 0] [50, 50]
从第一列构建第二列是非常简单的:
[ 0, 0] [ 50, 50] [ 0, 50] [ 50, 100] [50, 0] [100, 50] [50, 50] [100, 100]
这是一个三维案例{[0,0,0],[100,100,60]},delta = [50,50,30]
[ 0, 0, 0] [ 50, 50, 30] [ 0, 0, 30] [ 50, 50, 60] [ 0, 50, 0] [ 50, 100, 30] [ 0, 50, 30] [ 50, 100, 60] [50, 0, 0] [100, 50, 30] [50, 0, 30] [100, 50, 60] [50, 50, 0] [100, 100, 30] [50, 50, 30] [100, 100, 60]
答案 1 :(得分:1)
在所有维度(在Python中)拆分框的函数:
def halfboxes(box):
result = [[]]
for (a, b) in box:
result = [r + [(a, (a+b)/2)] for r in result] + \
[r + [((a+b)/2, b)] for r in result]
return result
h = halfboxes([(0,100), (20, 100)])
# Results in h =
# [[(0, 50), (20, 60)], [(50, 100), (20, 60)],
# [(0, 50), (60, 100)], [(50, 100), (60,100)]]
如果这是一个好的解决方案,也取决于您的性能要求。它会生成大量的数组副本,但效率并不高。但它对你的用例来说可能已经足够好了。
更高效的版本,不会复制任何数组:
def halfboxes(box):
# total number of resulting arrays
resultscount = 2**len(box)
# allocate |resultscount| arrays
results = [[] for i in range(resultscount)]
spread = 1
for (a,b) in box:
low = (a, (a+b)/2)
high = ((a+b)/2, b)
for i in range(resultscount):
# "magic" to append the high/low parts to the correct array
if i % (spread*2) < spread:
results[i].append(low)
else:
results[i].append(high)
spread *= 2
return results
这里没有复制数组,并且索引上的一些计算用于决定应该添加新边界的位置。
答案 2 :(得分:1)
尺寸n:最小[0,0,0,..,0] - 最大[delta 1 / 2,delta 2 / 2,... ,delta n / 2]
(当然下面的代码没有经过优化组织......)
using System;
using System.Collections.Generic;
namespace WindowsFormsApplication1
{
public class Class1
{
public static List<Box> GetSmallBoxes(Box bigBox)
{
int translationCoef;
List<Box> boxes = new List<Box>();
Box box;
for (int k = 0; k < Math.Pow(2, bigBox.Dimension); k++)
{
box = new Box(bigBox.Dimension);
for (int d = 0; d < bigBox.Dimension; d++)
{
translationCoef = ((int)(k / Math.Pow(2, bigBox.Dimension - d - 1)) % 2) == 0 ? 1 : 0;
box.Mins[d] = bigBox.Mins[d] + (bigBox.Deltas[d] / 2) * translationCoef;
box.Maxs[d] = bigBox.Mins[d] + (bigBox.Deltas[d] / 2) * (1 + translationCoef);
}
boxes.Add(box);
}
return boxes;
}
public static void Main()
{
Box bigBox = new Box(5);
bigBox.Mins = new int[] { 0, 10, 30, 20, 40 };
bigBox.Maxs = new int[] { 80, 50, 110, 40, 50 };
List<Box> smallBoxes = Class1.GetSmallBoxes(bigBox);
}
}
public class Box
{
public int Dimension;
public int[] Mins;
public int[] Maxs;
public Box(int dimension)
{
Dimension = dimension;
Mins = new int[dimension];
Maxs = new int[dimension];
}
public int[] Deltas
{
get
{
int[] deltas = new int[Dimension];
for (int i = 0; i < Dimension; i++)
{
deltas[i] = Maxs[i] - Mins[i];
}
return deltas;
}
}
public override string ToString()
{
string str;
str = "Min[";
foreach (int min in Mins)
{
str += min.ToString() + ", ";
}
str = str.Substring(0, str.Length - 2);
str += "] -- Max[";
foreach (int max in Maxs)
{
str += max.ToString() + ", ";
}
str = str.Substring(0, str.Length - 2);
return str;
}
}
}