将锯齿状的2d列表转置为1d列表

时间:2012-07-15 21:59:55

标签: c# wpf geometry jagged-arrays

我正在实施ZoomableCanvas http://blogs.msdn.com/b/kaelr/archive/2010/08/11/zoomableapplication2-a-million-items.aspx

它是一个WPF控件,允许在画布中虚拟显示对象。要利用虚拟化,库需要您在数据源对象上实现一个名为“Query”的方法。 Query方法懒惰地返回IEnumerable< int>给定一个Rect,其中int表示元素的数据源中的位置,而Rect是画布的可见区域(画布中不可见的项目不会被返回,因此不会被绘制)。对我的数据源进行排序,以便对X和Y值进行排序(myList [0]将包含最小的X,Y坐标)

鉴于此信息,我可以简单地执行以下操作来获取我的项目

int c = this.Count;

for (int j = 0; j < c; j++)
{
    if (rectangle.Contains(new Point(this[j].left, this[j].top)))
    {
       yield return (int)j;
    }
}

但是,我们遍历整个列表,列表中有100k +项。这表现得非常糟糕,尤其是当查看画布的右下角时,这些项目位于列表的末尾。

所以我尝试调换数据,以便我可以在画布上的可见区域中获取点,并确切知道数组中哪些索引对应。

        var tilewidth = MapWidthInTiles;

        for (var x = Math.Max(left, 0); x <= right; x++)
        {
            for (var y = Math.Max(top, 0); y <= bottom; y++)
            {

                var i = (y * tilewidth) + x;

                if (i < Count)
                {
                    yield return (int)i;
                }
            }
        }

除了我的数据集是不规则的(我正在绘制地图)之外,这是有效的,因为地图可能缺少或不完整的“瓷砖”。因此我的阵列基本上是锯齿状的。 Illustration of the jagged dataset missing 'tiles'

基本上,我正在寻找一种方法,可以在一维数组中快速识别给定二维几何的元素,其中二维数组中的元素可能不完整或连续。通常[y * widthOfAllItems] + x会给我正确的2d - &gt; 1d换位。但由于缺少元素,方程式关闭。任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:0)

您无需在1D数组中存储项目,您需要将它们返回到1D数组中的ZoomableCanvas。因此,请随意以您能想到的最有效的方式存储它们 QuadTree可能是一个存储点的解决方案:一个树,每个节点有4个子节点NE,SE,SW,NW,(NE =东北,......)每个节点都是空的,填充一种颜色,或者有还有4个孩子。 另一种解决方案:使用岛屿作为基础对象,使用边界框更快......并且可以将岛屿存储在树中。