C++ 2D 图形:平底三角形光栅化
C++ 2D Graphics: Flat Bottom Triangle Rasterization
我正在尝试使用 C++ 在 Windows 控制台上构建一个简单的 2D 应用程序来显示各种图元,因此我从最基本的图元开始:三角形。我可以正确显示三角形的轮廓和顶点,但在填充时遇到问题。我遇到过此处介绍的一些光栅化算法:http://www.sunshine2k.de/coding/java/TriangleRasterization/TriangleRasterization.html 并决定采用第一种方法。我复制了平底三角形案例的代码,但这似乎无法在我的应用程序上正常工作,我不知道问题的原因是什么。
我的结果:
main()
screen.fillFlatBottomTriangle(30,10, 10, 140/4, 256/2, 140/4, block_char, FG_CYAN);
screen.drawTriangle(30,10, 10, 140/4, 256/2, 140/4, block_char, BG_DARK_GREY);
screen.drawPixel(30,10,block_char,FG_RED);
screen.drawPixel(10,140/4,block_char,FG_GREEN);
screen.drawPixel(256/2,140/4,block_char,FG_MAGENTA);
fillFlatBottomTriangle
//http://www.sunshine2k.de/coding/java/TriangleRasterization/TriangleRasterization.html
void Screen::fillFlatBottomTriangle(int x1, int y1, int x2, int y2, int x3, int y3, short character, short color)
{
float invslope1 = (x2 - x1) / (y2 - y1);
float invslope2 = (x3 - x1) / (y3 - y1);
float curx1 = x1;
float curx2 = x1;
for (int scanlineY = y1; scanlineY <= y2; scanlineY++)
{
this->drawLine((int)curx1, scanlineY, (int)curx2, scanlineY, character, color);
curx1 += invslope1;
curx2 += invslope2;
}
}
画线
// https://en.wikipedia.org/wiki/Digital_differential_analyzer_(graphics_algorithm)
void Screen::drawLine(int x1, int y1, int x2, int y2, short character, short color)
{
float delta_x = x2 - x1;
float delta_y = y2 - y1;
float step;
if (abs(delta_x) >= abs(delta_y))
step = abs(delta_x);
else
step = abs(delta_y);
delta_x = delta_x / step;
delta_y = delta_y / step;
float x = x1;
float y = y1;
for (int i = 1; i <= step; i++)
{
this->drawPixel((int)x, (int)y, character, color);
x += delta_x;
y += delta_y;
}
}
绘制三角形
void Screen::drawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, short character, short color)
{
this->drawLine(x1,y1, x2, y2, character, color);
this->drawLine(x1,y1, x3, y3, character, color);
this->drawLine(x2,y2, x3, y3, character, color);
}
看这部分:(x2 - x1) / (y2 - y1)
由于这里所有的变量都是整数,所以这是整数除法。也就是说,除法的结果正在向 0 舍入。将结果分配给浮点数不会改变这一点。
要进行此浮点除法,您应该将至少一个操作数转换为浮点数:(x2 - x1) / (float) (y2 - y1)
您当前的代码将其中一个反斜率四舍五入为 0,从而在左侧生成垂直线。另一边的 x 值也没有增加得足够快,因为那部分也被四舍五入了。
我正在尝试使用 C++ 在 Windows 控制台上构建一个简单的 2D 应用程序来显示各种图元,因此我从最基本的图元开始:三角形。我可以正确显示三角形的轮廓和顶点,但在填充时遇到问题。我遇到过此处介绍的一些光栅化算法:http://www.sunshine2k.de/coding/java/TriangleRasterization/TriangleRasterization.html 并决定采用第一种方法。我复制了平底三角形案例的代码,但这似乎无法在我的应用程序上正常工作,我不知道问题的原因是什么。
我的结果:
main()
screen.fillFlatBottomTriangle(30,10, 10, 140/4, 256/2, 140/4, block_char, FG_CYAN);
screen.drawTriangle(30,10, 10, 140/4, 256/2, 140/4, block_char, BG_DARK_GREY);
screen.drawPixel(30,10,block_char,FG_RED);
screen.drawPixel(10,140/4,block_char,FG_GREEN);
screen.drawPixel(256/2,140/4,block_char,FG_MAGENTA);
fillFlatBottomTriangle
//http://www.sunshine2k.de/coding/java/TriangleRasterization/TriangleRasterization.html
void Screen::fillFlatBottomTriangle(int x1, int y1, int x2, int y2, int x3, int y3, short character, short color)
{
float invslope1 = (x2 - x1) / (y2 - y1);
float invslope2 = (x3 - x1) / (y3 - y1);
float curx1 = x1;
float curx2 = x1;
for (int scanlineY = y1; scanlineY <= y2; scanlineY++)
{
this->drawLine((int)curx1, scanlineY, (int)curx2, scanlineY, character, color);
curx1 += invslope1;
curx2 += invslope2;
}
}
画线
// https://en.wikipedia.org/wiki/Digital_differential_analyzer_(graphics_algorithm)
void Screen::drawLine(int x1, int y1, int x2, int y2, short character, short color)
{
float delta_x = x2 - x1;
float delta_y = y2 - y1;
float step;
if (abs(delta_x) >= abs(delta_y))
step = abs(delta_x);
else
step = abs(delta_y);
delta_x = delta_x / step;
delta_y = delta_y / step;
float x = x1;
float y = y1;
for (int i = 1; i <= step; i++)
{
this->drawPixel((int)x, (int)y, character, color);
x += delta_x;
y += delta_y;
}
}
绘制三角形
void Screen::drawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, short character, short color)
{
this->drawLine(x1,y1, x2, y2, character, color);
this->drawLine(x1,y1, x3, y3, character, color);
this->drawLine(x2,y2, x3, y3, character, color);
}
看这部分:(x2 - x1) / (y2 - y1)
由于这里所有的变量都是整数,所以这是整数除法。也就是说,除法的结果正在向 0 舍入。将结果分配给浮点数不会改变这一点。
要进行此浮点除法,您应该将至少一个操作数转换为浮点数:(x2 - x1) / (float) (y2 - y1)
您当前的代码将其中一个反斜率四舍五入为 0,从而在左侧生成垂直线。另一边的 x 值也没有增加得足够快,因为那部分也被四舍五入了。