使用2D数组在Java中栅格化三角形

时间:2015-08-08 10:03:18

标签: java arrays algorithm 3d rasterizing

我正在使用Java创建3D渲染器,但在尝试使用纯色填充渲染多边形时遇到问题。它工作得非常好但是经常会撕裂,但我不确定是不是因为算法效率低或者它是别的东西,因为它只是在顶点&# 39;它正在撕裂。这是一张图片:

example

线框: enter image description here 您可以看到顶点附近或者更确切地说是它撕裂的多边形点。我将像素的颜色存储在二维数组中,然后在其中循环并渲染它们。即使我使多边形非常小,它仍然会流泪,所以我不认为这是一个性能问题。我使用Bresham算法并将像素存储在二维数组中然后在多边形中我得到像素并将它们组成一个大数组,我循环向下然后穿过x直到我击中一个像素。将其设置为beginLine,然后将最后一个设置为endLine。然后我在这些点之间画一条线。

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();
}

基本上我的问题是: 这种算法是否效率低下,如果是这样,那会更好吗? 为什么它只在顶点附近撕裂?

2 个答案:

答案 0 :(得分:1)

在问题描述中,无法断定附加图像没有显示您想要的内容。从技术上讲,粉色区域可以描绘一组你“正确”绘制的三角形(即完全按照你想要的方式):p你可以将你打算在图像中的三角形标记为更新。我怀疑有4个三角形,但有更多这样的可能组合。

首先,由于每个y确定beginLineendLine的部分似乎是正确的,因此在绘制时您应该迭代到endLine相关的垂直线段(而不是endLine-1)。

但这可能不是真正的问题。尝试一次绘制一个三角形。如果某些三角形仍然渲染不正确,也会尝试查看消除最后一个部分(渲染矢量和顶点的部分)时会发生什么。为什么这个?!考虑到您的实施,您希望每个y只有一个细分。您提供的图像表明您的实施有时会呈现多个细分。因此,矢量和顶点的渲染可能不正确,但渲染多个“未完全对齐”的三角形也可能导致它。

如果这也没有解决,三角形之间可能会有一些小的偏移。试着看看为什么会这样。

与效率相关,这不是错误的。一般来说,效率和正确性与此无关。

修改

您应在endLine = x之后添加beginLine = x。如果您的实现只是在垂直线上只有一个像素,则不会绘制它(因为endLine将保持-1)。这是纠正此问题的一种方法。在开始绘图之前,还要检查beginLine是否大于-1。不要忘记从beginLine迭代到endLine

答案 1 :(得分:0)

您可以使用fillPolygon方法。

语法

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

注意: - 第一个值是右侧的坐标,第二个是中间点,第三个是左侧坐标。

使用类,变量和方法进行最终编程。

/*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);   
   }

}