Y-扫描线算法实现多边形区域填充:代码分析和实现步骤
该代码已经实现了 Y-扫描线算法来实现多边形区域填充。具体实现步骤如下:
-
确定多边形最大和最小 y 值,作为扫描线的上下限。
-
创建一个长度为 y_max - y_min + 1 的 vector 数组,用于存储 ET 和 AET。
-
遍历多边形的顶点,根据顶点的坐标计算出该边对应的 AET 节点,并将其插入到 ET 数组中。
-
对于每条扫描线,如果对应的 AET 非空,则对 AET 进行排序。根据当前扫描线的位置和 AET 中每个节点的 y_max 值,决定哪些边需要加入 AET。对于每个节点,如果其 y_max - 1 大于当前扫描线的位置,则将该节点信息传递给下一条扫描线的 AET。
-
对于 AET 中相邻的两个节点,根据其 x 坐标之间的距离,用 DrawPixel 函数画出扫描线上的像素。
void CPolygon_ConversionView::Active_Edge_Table_Conersion(int Vertices[][2], int VertexNum)
{
//确定多边形最大和最小y值
int y_max = Vertices[0][1], y_min = Vertices[0][1];
for (int i = 1; i < VertexNum; i++)
{
y_max = Vertices[i][1] > y_max ? Vertices[i][1] : y_max;
y_min = Vertices[i][1] < y_min ? Vertices[i][1] : y_min;
}
vector<AET> ET[1000];
//记录ET和AET
for (int i = 0; i < VertexNum; i++)
{
if (Vertices[i][1] < Vertices[(i + 1) % VertexNum][1])
{
AET node;
node.x = Vertices[i][0];
node.k_1 = (double)(Vertices[(i + 1) % VertexNum][0] - (double)Vertices[i][0]) / (double)(Vertices[(i + 1) % VertexNum][1] - (double)Vertices[i][1]);
node.y_max = Vertices[(i + 1) % VertexNum][1];
ET[Vertices[i][1] - y_min].push_back(node);
}
else
{
AET node;
node.x = Vertices[(i + 1) % VertexNum][0];
node.k_1 = (double)(Vertices[(i + 1) % VertexNum][0] - (double)Vertices[i][0]) / (double)(Vertices[(i + 1) % VertexNum][1] - (double)Vertices[i][1]);
node.y_max = Vertices[i][1];
ET[Vertices[(i + 1) % VertexNum][1] - y_min].push_back(node);
}
}
//进行填充
for (int i = 0; i <= y_max - y_min; i++)
{
//这条扫描线对应的AET非空
if (ET[i].size() > 0)
{
//先进行排序
sort(ET[i].begin(), ET[i].end(), cmp);
bool b = false;
//记录要连线的起始点
int x1;
for (int j = 0; j < ET[i].size(); j++)
{
if (b)
{
for (int x = x1; x <= ET[i][j].x; x++)
{
DrawPixel(x, i + y_min);
}
b = !b;
}
else
{
x1 = ET[i][j].x;
b = !b;
}
if (ET[i][j].y_max - 1 > i + y_min)
{
//将该边的信息传递给下一条扫描线
AET node = ET[i][j];
node.x = ET[i][j].x + ET[i][j].k_1;
ET[i + 1].push_back(node);
}
}
}
}
return;
}
原文地址: https://www.cveoy.top/t/topic/mUhI 著作权归作者所有。请勿转载和采集!