Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rasterizing a Triangle in Java using 2D array

I am creating a 3D renderer in Java but I have a problem when trying to render the polygons with a solid color fill. It works perfectly fine but every so often it's tearing but I'm not sure whether it is because the algorithm is inefficient or if it's something else because it's only at the vertices's it is tearing. Here is a picture:

example

Wireframe: enter image description here You can see that near the vertices's or rather points of the polygons it tears. I'm storing the color of the pixels in a 2 dimensional array and then cycling through it and rendering them. It still tears even when I make the polygon's really small so I don't think it's a performance problem. I use the Bresham algorithm and store the pixels in a 2 dimensional array then in the polygon I get the pixels and make them into one big array which I cycle through down the y and then across the x until I hit a pixel. That is set as beginLine and then the last one is set as endLine. I then draw a line between the points.

public void render()
{
    int tempPixels[][] = new int[(int) Math.max(vertex_1.getX(), Math.max(vertex_2.getX(), vertex_3.getX())) + 30][(int) Math.max(vertex_1.getY(), Math.max(vertex_2.getY(), vertex_3.getY())) + 30];

    for (int x = 0; x < vector_1.getWidth(); x++)
    {
        for (int y = 0; y < vector_1.getHeight(); y++)
        {
            if (vector_1.getPixels()[x][y] == 1)
            {
                tempPixels[(int) (x + Math.min(vertex_1.getX(), vertex_2.getX()))][(int) (y + Math.min(vertex_1.getY(), vertex_2.getY()))] = 1;
            }
        }
    }

    for (int x = 0; x < vector_2.getWidth(); x++)
    {
        for (int y = 0; y < vector_2.getHeight(); y++)
        {
            if (vector_2.getPixels()[x][y] == 1)
            {
                tempPixels[(int) (x + Math.min(vertex_2.getX(), vertex_3.getX()))][(int) (y + Math.min(vertex_2.getY(), vertex_3.getY()))] = 1;
            }
        }
    }

    for (int x = 0; x < vector_3.getWidth(); x++)
    {
        for (int y = 0; y < vector_3.getHeight(); y++)
        {
            if (vector_3.getPixels()[x][y] == 1)
            {
                tempPixels[(int) (x + Math.min(vertex_3.getX(), vertex_1.getX()))][(int) (y + Math.min(vertex_3.getY(), vertex_1.getY()))] = 1;
            }
        }
    }

    for (int y = 0; y < (int) Math.max(vertex_1.getY(), Math.max(vertex_2.getY(), vertex_3.getY())) + 4; y++)
    {
        int beginLine = -1;

        int endLine = -1;

        for (int x = 0; x < (int) Math.max(vertex_1.getX(), Math.max(vertex_2.getX(), vertex_3.getX())) + 4; x++)
        {
            if (tempPixels[x][y] == 1)
            {
                if (beginLine == -1)
                {
                    beginLine = x;
                }
                else
                {
                    endLine = x;
                }
            }
        }

        for (int i = beginLine; i < endLine; i++)
        {
            pixels[i][y] = 1;
            colors[i][y] = Color.PINK;
        }
    }

    vector_1.render();
    vector_2.render();
    vector_3.render();

    vertex_1.render();
    vertex_2.render();
    vertex_3.render();
}

So basically my questions are: Is this algorithm inefficient, if so what would be a better way? Why is it tearing near the vertices's only?

like image 350
Hyden Avatar asked Aug 08 '26 04:08

Hyden


1 Answers

Out of the problem description one cannot conclude that the attached image does not show what you want. Technically, the pink zone could depict a set of triangles you have 'correctly' painted (i.e. exactly the way you intended to) :p You could mark the triangles that you intended to be in the image, as an update. I suspect there are 4 triangles, though there are more such possible combinations.

First of all, since the part that, for each y, determines the beginLine and endLine seems to be correct, you should probably iterate till endLine when drawing the associated vertical segment (and not till endLine-1).

But that is probably not the real problem. Try drawing one triangle at a time. If some triangles still render incorrectly also try to see what happens when you eliminate the last part (the one rendering the vectors and the vertices). Why this?! Considering your implementation, you expect just a segment on each y. The image you provided indicates that your implementation sometimes renders more than one segment. So the rendering of the vectors and the vertices might be incorrect, though rendering multiple 'not perfectly aligned' triangles could also cause it.

If this does not solve it either, there might be some small offset in between your triangles. Try to see why that is.

Related to efficiency, that is not at fault. Generally, efficiency and correctness are not related in this way.

EDIT

You should add endLine = x after beginLine = x. With your implementation if you only have one pixel on a vertical line you do not draw it (since endLine will stay -1). This is one way to correct this issue. Also check that beginLine is greater than -1 before starting drawing. And do not forget to iterate from beginLine to exactly endLine.

like image 117
cobarzan Avatar answered Aug 09 '26 18:08

cobarzan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!