Hyden
Hyden

Reputation: 299

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?

Upvotes: 3

Views: 988

Answers (2)

Eeshaan Sethia
Eeshaan Sethia

Reputation: 7

You can use the method fillPolygon.

Syntax

g.setColor(Color.*color you want*)
g.fillPolygon (new int[]{width Dimensions}, new int [] {Height Dimensions}, no. of co-ordinates);

Note: - The 1st Value is of right Co-Ordinate, 2nd is of mid point and the 3rd is of Left Co-Ordinate.

The final programming with class, variables and methods.

/*Import the following files: -*/   
import javax.swing.JPanel;         
import javax.swing.JFrame;            
import java.awt.Color;    
import java.awt.Graphics;  
import java.awt.event.ComponentListener;  
import java.awt.event.ComponentEvent;  
import java.awt.Font; 

public class Shapes extends JPanel
{
    public Shapes() 
    {
        this.addComponentListener(new ComponentListener(){
            public void componentShown(ComponentEvent arg0) {

            }

            public void componentResized(ComponentEvent arg0) {
                paintComponent(getGraphics());

            }               

            public void componentMoved(ComponentEvent arg0) {                   

            }

            public void componentHidden(ComponentEvent arg0) {
                // TODO Auto-generated method stub

            }
        });

    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        this.setBackground(Color.MAGENTA);
        g.setColor(Color.BLUE);
        g.fillPolygon (new int[]{250,135,10}, new int [] {160,15,160}, 3);

        g.setFont(new Font("TimesRoman", Font.PLAIN, 35));
        g.setColor(Color.GREEN);
        g.drawString("Triangle", 75,  120); 
    }
    public static void main(String[] args) 
    {   
        Shapes obj = new Shapes();   
        JFrame frame = new JFrame("Shapes");   
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
        frame.add(obj);   
        frame.setSize(600, 500);   
        frame.setVisible(true);   
   }

}

Upvotes: 0

cobarzan
cobarzan

Reputation: 682

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.

Upvotes: 1

Related Questions