如何找到2D图形上的点所在的欧几里德“区域”?

时间:2012-03-21 18:40:08

标签: c# algorithm a-star pathfinder

我正在尝试加速我的A *实现(在10x10网格时非常糟糕的延迟!)并且性能最差可能来自此功能:

public Vector2 CoordsToIndex(Vector2 coords)
{
    for (int i = 0; i < mapCols; ++i)
    {
            for (int j = 0; j < mapRows; ++j)
            {
                if (coords.X >= i * map[0, 0].length &&
                    coords.X < i * map[0, 0].length + map[0, 0].length)
                {
                    indexi = i;
                }
                if (coords.Y >= j * map[0, 0].height &&
                    coords.Y < j * map[0, 0].height + map[0, 0].height)
                {
                    indexj = j;
                }
            }
    }
return new Vector2(indexi, indexj);
}

我最初的实现并不完全正确,但是如果我可以让它工作,那么它会加速很多事情(我经常使用这个功能):

// The below math isn't quite right
indexi = (int)((coords.X - (map[0, 0].length / 2)) / map[0, 0].length) - 1;
indexj = (int)((coords.Y - (map[0, 0].height / 2)) / map[0, 0].height) - 1;

if (indexi < 0)
{
    indexi = 0;
}

if (indexj < 0)
{
    indexj = 0;
}

map[0, 0].length是图块的长度,map[0, 0].height是图块的高度。所有瓷砖都是均匀的。

必须有可能提出一个公式来计算这个,但我不确定它会是什么。任何指针/帮助/答案将不胜感激!

编辑:呃...实际上我认为问题可能是减去长度或高度除以2。这对于瓷砖节点来说很好,因为我将它们的位置存储为瓷砖的中心,但为此它会将错误的瓷砖放回去......也许这就是问题......检查。

编辑:啊..就是那个AND删除-1。男人我很困惑,有趣的是我昨晚花了大约两个小时完全被这个混淆了然后在最后发帖寻求帮助之后几秒钟我就一闪而过。

解决方案:

public Vector2 CoordsToIndex(Vector2 coords)
{
    int indexi = (int)(coords.X / map[0, 0].length);
    int indexj = (int)(coords.Y / map[0, 0].height);

    return new Vector2(indexi, indexj);
}

看起来好多了。

2 个答案:

答案 0 :(得分:3)

嗯,简短的回答:

indexi = (int)(coords.X/map[0,0].length)
indexj = (int)(coords.Y/map[0,0].height)

编辑:当然,在我发布之前,OP编辑了几乎这个答案。 /捂脸

答案 1 :(得分:1)

这个怎么样:

for (int i = 0; i < mapCols; ++i) 
{ 
   if (coords.X >= i * map[0, 0].length && 
       coords.X < i * map[0, 0].length + map[0, 0].length) 
   { 
     indexi = i;
     break; // no need to continue the loop
   } 
} 
for (int j = 0; j < mapRows; ++j) 
{ 
  if (coords.Y >= j * map[0, 0].height && 
      coords.Y < j * map[0, 0].height + map[0, 0].height) 
  { 
    indexj = j; 
    break; // no need to continue the loop
  } 
} 

请注意,在原始代码中,循环遍历每个单元格以查找行和列,只需循环遍历行以查找行索引(对于列类似)。因此,现在你有20个(最多),而不是100个比较。

编辑:

当然是你自己的解决方案
int indexi = (int)(coords.X / map[0, 0].length); 
int indexj = (int)(coords.Y / map[0, 0].height); 

更优化:)