javaswingawtjava-2drasterizing

How to fill a triangle using lines?


I'm trying to fill a triangle using horizontal lines and I can't figure out what's wrong with my current method. Before anyone says to just use fillPolygon, I can't use that. I need to fill it using lines. It seems to work ok in some situations and completely break in others.

enter image description here

That's how it should look. But then I tried applying my method to a rotating 3D cube and...

enter image description here

I have no idea what's wrong. Also, the red borders are also one of my triangle methods. Those work perfectly and the filled triangles and the outlined triangles have the same vertices inputted.

public void filledTri(int x1,int y1,int x2,int y2,int x3,int y3){
    int[] xs = {x1,x2,x3};
    int[] ys = {y1,y2,y3};
    //Sort vertices in vertical order so A/1 is highest and C/3 is lowest
    int I,tempx,tempy;
    for(int i=1;i<3;i++){
        I = i-1;
        tempx = xs[i];
        tempy = ys[i];
        while(I>=0&&tempy<ys[I]){
            xs[I+1] = xs[I];
            ys[I+1] = ys[I];
            I--;
        }
        xs[I+1] = tempx;
        ys[I+1] = tempy;
    }
    //Set left and right edges
    linepts ab = new linepts(xs[0],ys[0],xs[1],ys[1]),
    ac = new linepts(xs[0],ys[0],xs[2],ys[2]);
    linepts[] lines = {ab.getEndX() < ac.getEndX() ? ab : ac,
    ab.getEndX() > ac.getEndX() ? ab : ac,
    new linepts(xs[1],ys[1],xs[2],ys[2])};
    //Fill triangle
    int startY = ys[0],endY = ys[2];
    for(int y=startY;y<=endY;y++){
        if(y>ys[1])
        horizontalLine((int)Math.round(lines[2].getX(y)),
        y,
        (int)Math.round(lines[1].getX(y)));
        else
        horizontalLine((int)Math.round(lines[0].getX(y)),
        y,
        (int)Math.round(lines[1].getX(y)));
    }

getX(int y) gets me the x coordinate where the line passes through the y value. If it's a horizontal line it just returns the line's start x

Point A is the highest on screen and the lowest value, B is the middle, and C is the lowest on screen and highest value

I'm using a buffered image on a jframe to draw it if that helps.


Solution

  • I've seen what you are doing in a Software Renderer tutorial. It is explained in this and this episodes.

    What he does there is scanning the longest to get every pixel on that line, it stores the min X value and max X value, (given by the other 2 lines). He originally makes it for specific triangles, but then he upgrades the code to accept generic triangles.

    Here's a nice diagram to explain that: enter image description here

    I assume what you're experiencing is because of projecting 3D triangles into 2D ones (clipping, triangles get infinite coordinates, or because you're program doesn't takes too well empty triangles.