使用3D中的扫描线方法进行栅格化时,相邻多边形的锯齿状边缘

时间:2016-11-14 15:29:32

标签: java algorithm math graphics 3d

我正在尝试使用扫描线方法在3D中栅格化三个三角形。但在处理完所有多边形之后,相邻多边形之间的边缘质量非常差。 渲染图片:

img

对于栅格化,我使用带有活动边缘表的扫描线方法。 每条扫描线仅与两条边相交。我存储交叉点(x,y,z)然后画线。 对于计算交叉点,我使用此类并为每个新扫描线调用活动边缘的update()方法:

public class Edge {
private Point3D start, end;
public double dx = 0, dy = 0, dzX = 0, dzY = 0, currX = 0, currY = 0, currZx = 0, currZy = 0;
private double calcCurrX = 0, calcCurrY = 0, calcCurrZx = 0, calcCurrZy = 0;
private double lx = 0, ly = 0,lz = 0;

public Edge(Point3D start, Point3D end) {
    this.start = new Point3D(start);
    this.end = new Point3D(end);
    reset();
}

public void update(){
    calcCurrX += dx;
    calcCurrZx += dzX;//for drawing scanline slices
    calcCurrZy += dzY;//for use with scanline
    calcCurrY += dy;
    currX = calcCurrX + 0.5;
    currY = calcCurrY + 0.5;
    currZx = calcCurrZx + 0.5;
    currZy = calcCurrZy + 0.5;
}

public Point3D getStart() {
    return start;
}

public void setStart(Point3D start) {
    this.start = start;
    reset();
}

public Point3D getEnd() {
    return end;
}

public void setEnd(Point3D end) {
    this.end = end;
    reset();
}

public void reset(){
    lx = this.end.x - this.start.x;
    ly = this.end.y - this.start.y;
    lz = this.end.z - this.start.z;
    dx = lx / ly;
    dy = ly / ly;
    dzX = lz / lx;
    dzY = lz / ly;

    calcCurrX = this.start.x;// + 0.5 * Math.signum(dx);
    calcCurrZx = this.start.z;// + 0.5 * Math.signum(dzX);
    calcCurrZy = this.start.z;// + 0.5 * Math.signum(dzY);
    calcCurrY = this.start.y;// + 0.5 * Math.signum(dy);
    currX = calcCurrX + 0.5;
    currY = calcCurrY + 0.5;
    currZx = calcCurrZx + 0.5;
    currZy = calcCurrZy + 0.5;
}}

这是循环遍历所有扫描线的代码,计算交叉点并绘制线条:

int scanlineEnd = (int) edges[0].getEnd().y;
    for (Edge edge : edges) {
        if (scanlineEnd < (int) edge.getEnd().y)
            scanlineEnd = (int) edge.getEnd().y;
    }

    scanlineEnd = Math.min(scanlineEnd, zBuffer[0].length);

    int scanline = (int) edges[0].getStart().y;

    ArrayList<Edge> activeEdges = computeActiveEdges(edges, scanline);

    while (scanline < scanlineEnd){
        if(activeEdges.isEmpty()) break;

        if(scanline == (int) activeEdges.get(0).getEnd().y || scanline == (int) activeEdges.get(1).getEnd().y){
            activeEdges = computeActiveEdges(edges, scanline);
        }

        if (scanline < 0){
            activeEdges.get(0).update();
            activeEdges.get(1).update();
            scanline++;
            continue;
        }

        Point3D start = new Point3D((int) activeEdges.get(0).currX, (int) activeEdges.get(0).currY, (int) activeEdges.get(0).currZy);
        Point3D end = new Point3D((int) activeEdges.get(1).currX, (int) activeEdges.get(1).currY, (int) activeEdges.get(1).currZy);

        if (end.x < start.x) {
            Point3D temp = start;
            start = end;
            end = temp;
        }

        double dzX = 0;
        if ((int) start.x != (int) end.x) {
            dzX = (end.z - start.z) / (end.x - start.x);
        }

        int y = (int) start.y;
        double currZx = start.z;
        //int zMin = findMinZ(coordinatesT), zMax = findMaxZ(coordinatesT);
        for (int x = (int) start.x; x <= (int) end.x; x++) {
            if (x >= 0 && x < zBuffer.length) {
                if (zBuffer[x][y] < (int) currZx) {
                    image.setRGB(x, y, color.getRGB());
                    zBuffer[x][y] = (int) (currZx);
                }
            }
            currZx += dzX; //here i compute z for line that connects two intersection points. I think i'm doing it incorrect
        }
        activeEdges.get(0).update();
        activeEdges.get(1).update();

        scanline++;
    }

如何在多边形之间获得更好的边缘质量?

0 个答案:

没有答案