首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >遍历2.5D网格

遍历2.5D网格
EN

Stack Overflow用户
提问于 2012-07-28 04:00:40
回答 3查看 877关注 0票数 1

我正在尝试找出如何以有效的方式遍历2.5D网格。网格本身是二维的,但是网格中的每个单元格都有一个浮动的最小/最大高度。要遍历的直线由两个三维浮点坐标定义。如果进入/退出网格单元格之间的z值范围与该单元格的最小/最大高度不重叠,我希望停止遍历这条线。

我目前正在使用2D DDA算法按顺序遍历网格单元(见图),但我不确定当到达每个网格单元时如何计算z值。如果我可以这样做,我就可以测试进入/离开单元格时的z值与单元格的最小/最大高度。

有没有办法修改这个算法,允许在输入每个网格单元时计算z?或者,有没有更好的遍历算法可以让我这样做?

下面是我正在使用的当前代码:

代码语言:javascript
复制
void Grid::TraceGrid(Point3<float>& const start, Point3<float>& const end, GridCallback callback )
{
    // calculate and normalize the 2D direction vector
    Point2<float> direction=end-start;
    float length=direction.getLength( );
    direction/=length;

    // calculate delta using the grid resolution
    Point2<float> delta(m_gridresolution/fabs(direction.x), m_gridresolution/fabs(direction.y));

    // calculate the starting/ending points in the grid
    Point2<int> startGrid((int)(start.x/m_gridresolution), (int)(start.y/m_gridresolution));
    Point2<int> endGrid((int)(end.x/m_gridresolution), (int)(end.y/m_gridresolution));
    Point2<int> currentGrid=startGrid;

    // calculate the direction step in the grid based on the direction vector
    Point2<int> step(direction.x>=0?1:-1, direction.y>=0?1:-1);

    // calculate the distance to the next grid cell from the start
    Point2<float> currentDistance(((step.x>0?start.x:start.x+1)*m_gridresolution-start.x)/direction.x, ((step.y>0?start.y:start.y+1)*m_gridresolution-start.y)/direction.y);

    while(true)
    {
        // pass currentGrid to the callback
        float z = 0.0f;     // need to calculate z value somehow
        bool bstop=callback(currentGrid, z);

        // check if the callback wants to stop or the end grid cell was reached
        if(bstop||currentGrid==endGrid) break;

        // traverse to the next grid cell
        if(currentDistance.x<currentDistance.y) {
            currentDistance.x+=delta.x;
            currentGrid.x+=step.x;
        } else {
            currentDistance.y+=delta.y;
            currentGrid.y+=step.y;
        }
    }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-07-31 02:25:00

我想出了一个好办法。添加到函数的开头:

代码语言:javascript
复制
float fzoffset=end.z-start.z;
Point2<float> deltaZ(fzoffset/fabs(end.x-start.x), fzoffset/fabs(end.y-start.y));
Point2<float> currentOffset((step.x>0?start.x:start.x+1)*m_gridresolution-start.x, (step.y>0?start.y:start.y+1)*m_gridresolution-start.y);

在currentDistance.x/.y递增的循环中,添加:

代码语言:javascript
复制
currentOffset.x+=m_gridresolution;  //When stepping in the x axis
currentOffset.y+=m_gridresolution;  //When stepping in the y axis

然后计算每一步的z:

代码语言:javascript
复制
z=currentOffset.x*deltaZ.x+start.z;  //When stepping in the x axis
z=currentOffset.y*deltaZ.y+start.z;  //When stepping in the y axis
票数 0
EN

Stack Overflow用户

发布于 2012-07-28 05:16:00

看起来Bresenham Line Algorithm的3D扩展应该行得通了。您将在X上迭代并独立跟踪线段的Y和Z分量的误差,以确定每个相应X值的Y和Z值。当Z中的累积误差达到某个临界值时,您就会停止,这表明它超出了您的最小/最大值。

票数 0
EN

Stack Overflow用户

发布于 2012-07-28 07:43:08

对于每个单元格,您知道您来自哪个单元格。这意味着你知道你来自哪一边。在绿线和给定网格线的交点处计算z看起来很简单。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11694886

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档