2

我正在用 Java 创建一个 3D 渲染器,但是在尝试使用纯色填充渲染多边形时遇到了问题。它工作得很好,但它经常撕裂,但我不确定是因为算法效率低下还是因为它只是在顶点处撕裂。这是一张图片:

例子

线框: 在此处输入图像描述 您可以看到它撕裂的多边形的顶点或点附近。我将像素的颜色存储在二维数组中,然后循环遍历并渲染它们。即使我使多边形非常小,它仍然会流泪,所以我认为这不是性能问题。我使用 Bresham 算法并将像素存储在一个二维数组中,然后在多边形中我得到像素并将它们变成一个大数组,我在 y 上循环,然后在 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();
}

所以基本上我的问题是:这个算法效率低下,如果是这样,什么是更好的方法?为什么它只在顶点附近撕裂?

4

2 回答 2

1

从问题描述中无法得出结论,所附图像未显示您想要的内容。从技术上讲,粉红色区域可以描绘一组您已经“正确”绘制的三角形(即完全按照您的意图):p 您可以将您想要在图像中的三角形标记为更新。我怀疑有 4 个三角形,尽管有更多这样的可能组合。

首先,由于对于 eachy确定beginLineand的部分endLine似乎是正确的,因此您可能应该迭代直到endLine绘制相关的垂直线段(而不是直到endLine-1)。

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

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

与效率有关,这没有错。一般来说,效率和正确性是没有这种关系的。

编辑

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

于 2015-08-08T12:29:50.370 回答
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);   
   }

}
于 2017-06-21T08:05:49.783 回答