算法及优化理论参考文章:
图形学底层探秘 - 更现代的三角形光栅化与插值算法的实现与优化 - 知乎
如何判断一个点在三角形内部_c语言判断点在三角形内_pdcxs007的博客-CSDN博客
代码实现如下:
void FillTriangle(const PointLong v1, const PointLong v2, const PointLong v3, GR_COLOR color)
{
// 第一步找出XMAX YMAX XMIN YMIN找出最小矩形
int xMIN, xMAX, yMIN, yMAX;
xMIN = (v1.x < v2.x ? v1.x : v2.x) < v3.x ? (v1.x < v2.x ? v1.x : v2.x) : v3.x;
xMAX = (v1.x > v2.x ? v1.x : v2.x) > v3.x ? (v1.x > v2.x ? v1.x : v2.x) : v3.x;
yMIN = (v1.y < v2.y ? v1.y : v2.y) < v3.y ? (v1.y < v2.y ? v1.y : v2.y) : v3.y;
yMAX = (v1.y > v2.y ? v1.y : v2.y) > v3.y ? (v1.y > v2.y ? v1.y : v2.y) : v3.y;
if (yMIN >= SCREEN_HEIGHT)
{
return;
}
if (yMAX <= 0)
{
return;
}
if (xMIN >= SCREEN_WIDTH)
{
return;
}
if (xMAX <= 0)
{
return;
}
if (yMIN < 0)
{
yMIN = 0;
}
if (yMAX >= SCREEN_HEIGHT)
{
yMAX = SCREEN_HEIGHT - 1;
}
if (xMIN < 0)
{
xMIN = 0;
}
if (xMAX >= SCREEN_WIDTH)
{
xMAX = SCREEN_WIDTH - 1;
}
float signOfTrig = (v2.x - v1.x) * (v3.y - v1.y) - (v2.y - v1.y) * (v3.x - v1.x);
float addX1 = (v2.x - v1.x);
float addY1 = (v2.y - v1.y);
float addX2 = (v3.x - v2.x);
float addY2 = (v3.y - v2.y);
float addX3 = (v1.x - v3.x);
float addY3 = (v1.y - v3.y);
float startXAB = addX1 * (yMIN - v1.y) - addY1 * (xMIN - v1.x);
float startXCA = addX3 * (yMIN - v3.y) - addY3 * (xMIN - v3.x);
float startXBC = addX2 * (yMIN - v2.y) - addY2 * (xMIN - v2.x);
for (int i = xMIN; i <= xMAX; ++i)
{
bool bStart = false;
float signOfAB = startXAB;
float signOfCA = startXCA;
float signOfBC = startXBC;
for (int j = yMIN; j < yMAX; j++)
{
PointLong p = { i, j };
bool bInTri = false;
if (signOfTrig > 0)
{
bInTri = (signOfAB >= 0) && (signOfCA >= 0) && (signOfBC >= 0);
}
else
{
bInTri = (signOfAB <= 0) && (signOfCA <= 0) && (signOfBC <= 0);
}
if (bInTri)
{
bStart = true;
MemSetColor(wndbuf + i + j * wndTwidth, color, 1);
}
else
{
if (bStart)
{
break;
}
}
signOfAB += addX1;
signOfBC += addX2;
signOfCA += addX3;
}
startXAB -= addY1;
startXBC -= addY2;
startXCA -= addY3;
}
}// FillTriangle end