2012-07-15 158 views
0

我实现ZoomableCanvas http://blogs.msdn.com/b/kaelr/archive/2010/08/11/zoomableapplication2-a-million-items.aspx移调锯齿状2D名单1D名单

这是一个WPF控件,允许在一个画布对象的虚拟显示。为了利用虚拟化,该库要求您在数据源对象上实现一个名为“查询”的方法。 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; 
    } 
} 

但是,我们遍历整个列表,并且列表中有100多个项目。这种情况非常糟糕,特别是当查看画布的右下角时,这些项目位于列表的末尾。

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

 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'

基本上,我正在寻找一种方法,可以在2D阵列中的元素可能不完整或连续的情况下,快速识别给定2D元素的元素。通常[y * widthOfAllItems] + x会给我适当的2d - > 1d换位。但由于缺少的元素,方程式是关闭的。任何帮助表示赞赏!

回答

0

您不需要在1D数组中存储您的项目,您需要将它们返回到1D数组中的ZoomableCanvas。因此,请随时以最有效的方式将其存储起来。四叉树可能是一个解决方案来存储你的观点:一个树,每个节点有4个孩子NE,SE,SW,NW(NE =东北,...),每个节点或者是空的,用一种颜色填充,或者也有4个孩子。 另一种解决方案:与岛屿一起作为基础对象,使用边界框加快速度....也许将岛屿存储在树中。