基本上,我想使用换行算法来确定要检查raycaster碰撞的单元格。

Bresenham不适用于此,因为它使用统一厚度方法,这意味着它会忽略那些至少不会覆盖该行的单元格。一点也不好,因为这意味着未检查我的线的某些线段是否与像元相交,从而导致错误。

我似乎找不到任何“粗线”算法,有人可以帮助我找到一个算法吗?

格林:我想要什么。
红色:我目前拥有和不想要的。

最佳答案

我遇到了与您完全相同的问题,并找到了一个非常简单的解决方案。通常,布雷森纳姆有两个连续的if来确定是否应增加两个维度的坐标:

public void drawLine(int x0, int y0, int x1, int y1, char ch) {
    int dx =  Math.abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
    int dy = -Math.abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
    int err = dx + dy, e2; // error value e_xy

    for (;;) {
        put(x0, y0, ch);

        if (x0 == x1 && y0 == y1) break;

        e2 = 2 * err;

        // horizontal step?
        if (e2 > dy) {
            err += dy;
            x0 += sx;
        }

        // vertical step?
        if (e2 < dx) {
            err += dx;
            y0 += sy;
        }
    }
}

现在,您要做的就是在第二个else之前插入一个if:
public void drawLineNoDiagonalSteps(int x0, int y0, int x1, int y1, char ch) {
    int dx =  Math.abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
    int dy = -Math.abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
    int err = dx + dy, e2;

    for (;;) {
        put(x0, y0, ch);

        if (x0 == x1 && y0 == y1) break;

        e2 = 2 * err;

        // EITHER horizontal OR vertical step (but not both!)
        if (e2 > dy) {
            err += dy;
            x0 += sx;
        } else if (e2 < dx) { // <--- this "else" makes the difference
            err += dx;
            y0 += sy;
        }
    }
}

现在,该算法不再一次更改两个坐标。
我尚未对此进行彻底的测试,但它似乎工作得很好。

关于c# - 线光栅化: Cover all pixels,不管线梯度如何?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4381269/

10-09 16:36