功能:X-扫描线转换算法 参数说明: vertices2---顶点列表 VertexNum ---顶点数目备注: DrawPixelint x int y --绘制像素点x yvoid CPolygon_ConversionViewX_Scan_Line_Conersionint Vertices2 int VertexNum return;根据要求完成x扫描线算法代码并添
/********************************************************************* 功能:X-扫描线转换算法
参数说明: vertices[][2]---顶点列表 VertexNum ---顶点数目 备注: DrawPixel(int x, int y) --绘制像素点(x, y) **********************************************************************/ void CPolygon_ConversionView::X_Scan_Line_Conersion(int Vertices[][2], int VertexNum) { // 1. 找出多边形的边界 int ymax = Vertices[0][1]; // 最高点 int ymin = Vertices[0][1]; // 最低点 for (int i = 1; i < VertexNum; i++) { if (Vertices[i][1] > ymax) ymax = Vertices[i][1]; if (Vertices[i][1] < ymin) ymin = Vertices[i][1]; }
// 2. 初始化活性边表和活性点表
vector<EDGE> AEL; // 活性边表
vector<int> APL; // 活性点表
vector<EDGE> ET; // 边表
EDGE edge;
for (int i = 0; i < VertexNum; i++)
{
int x1 = Vertices[i][0];
int y1 = Vertices[i][1];
int x2 = Vertices[(i + 1) % VertexNum][0];
int y2 = Vertices[(i + 1) % VertexNum][1];
// 如果边不是水平的,则加入边表
if (y1 != y2)
{
if (y1 > y2) // 确保y1<y2,即边从下到上
{
swap(x1, x2);
swap(y1, y2);
}
edge.x = x1;
edge.ymin = y1;
edge.ymax = y2;
edge.k = (float)(x2 - x1) / (float)(y2 - y1);
ET.push_back(edge);
}
}
sort(ET.begin(), ET.end(), cmp); // 按 ymin 升序排序
// 3. 从上到下按扫描线处理多边形
for (int y = ymax; y >= ymin; y--)
{
// 3.1 将y = y 的边加入到活性边表
for (auto it = ET.begin(); it != ET.end();)
{
if (it->ymin == y)
{
AEL.push_back(*it);
it = ET.erase(it);
}
else
it++;
}
// 3.2 从活性边表中删除y = y 的边
for (auto it = AEL.begin(); it != AEL.end();)
{
if (it->ymax == y)
it = AEL.erase(it);
else
it++;
}
// 3.3 更新活性边表中所有边的x值
for (auto it = AEL.begin(); it != AEL.end(); it++)
it->x += it->k;
// 3.4 将活性边表中的边按x值升序排序
sort(AEL.begin(), AEL.end(), cmpx);
// 3.5 根据活性边表中的边绘制像素
for (int i = 0; i < AEL.size(); i += 2)
{
int x1 = (int)ceil(AEL[i].x);
int x2 = (int)ceil(AEL[i + 1].x);
for (int x = x1; x < x2; x++)
DrawPixel(x, y);
}
}
return;
}
原文地址: https://www.cveoy.top/t/topic/bdX3 著作权归作者所有。请勿转载和采集!