使用2D数组在Java中光栅化三角形
我正在用Java创建一个3D渲染器,但在尝试使用纯色填充渲染多边形时遇到了一个问题。它工作得非常好,但经常会撕裂,但我不确定这是因为算法效率低下还是因为它只是在顶点处撕裂。这是一张照片: 线框: 您可以看到,在顶点附近,或者更确切地说,在它撕裂的多边形的点附近。我将像素的颜色存储在二维数组中,然后在其中循环并渲染它们。即使我使多边形非常小,它仍然会撕裂,所以我不认为这是性能问题。我使用Bresham算法,将像素存储在一个二维数组中,然后在多边形中,我得到像素,并将它们做成一个大数组,我沿着y循环,然后穿过x,直到我碰到一个像素。将其设置为beginLine,然后将最后一个设置为endLine。然后我在两个点之间画一条线使用2D数组在Java中光栅化三角形,java,arrays,algorithm,3d,rasterizing,Java,Arrays,Algorithm,3d,Rasterizing,我正在用Java创建一个3D渲染器,但在尝试使用纯色填充渲染多边形时遇到了一个问题。它工作得非常好,但经常会撕裂,但我不确定这是因为算法效率低下还是因为它只是在顶点处撕裂。这是一张照片: 线框: 您可以看到,在顶点附近,或者更确切地说,在它撕裂的多边形的点附近。我将像素的颜色存储在二维数组中,然后在其中循环并渲染它们。即使我使多边形非常小,它仍然会撕裂,所以我不认为这是性能问题。我使用Bresham算法,将像素存储在一个二维数组中,然后在多边形中,我得到像素,并将它们做成一个大数组,我沿着y循
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();
}
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(),vertext_3.getY())+30];
对于(int x=0;x
所以基本上我的问题是:
这种算法效率低吗?如果是这样,还有什么更好的方法?
为什么它只在顶点附近撕裂?根据问题描述,无法得出附加图像没有显示所需内容的结论。从技术上讲,粉色区域可以描绘一组您“正确”绘制的三角形(即,完全按照您打算的方式):p您可以标记您打算在图像中显示的三角形,作为更新。我怀疑有4个三角形,尽管有更多这样的可能组合 首先,由于为每个
y
确定beginLine
和endLine
的部分似乎是正确的,因此在绘制相关垂直段时,您可能应该迭代到endLine
(而不是直到endLine-1
)
但这可能不是真正的问题。试着一次画一个三角形。如果某些三角形仍然渲染不正确,请尝试查看消除最后一部分(渲染向量和顶点的部分)时会发生什么情况。为什么会这样?!考虑到您的实现,您希望每个y
上只有一个段。您提供的图像表明,您的实现有时会渲染多个片段。因此,矢量和顶点的渲染可能不正确,尽管渲染多个“未完全对齐”的三角形也可能导致错误
如果这也不能解决问题,三角形之间可能会有一些小的偏移。试着看看这是为什么
与效率有关,这不是错。一般来说,效率和正确性是不相关的
编辑
您应该在
beginLine=x
之后添加endLine=x
。在您的实现中,如果一条垂直线上只有一个像素,则不会绘制它(因为endLine
将保持-1)。这是纠正此问题的一种方法。在开始绘图之前,还要检查beginLine
是否大于-1。不要忘记从beginLine
迭代到endLine
,您可以使用fillPolygon方法
语法
g.setColor(颜色。*您想要的颜色*)
g、 填充多边形(新的int[]{宽度尺寸},新的int[]{高度尺寸},坐标数)代码>
注:-第一个值为右坐标,第二个值为中点,第三个值为左坐标
带有类、变量和方法的最终编程。
/*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);
}
}
我没有真正理解第一部分,但我猜你的意思是你不能真正看到三角形在哪里。我添加了一个带有线框的图像。三角形在正确的位置。我现在要测试单个多边形。这似乎是个问题