功能:有效边表转换算法 参数说明: vertices2---顶点列表 VertexNum ---顶点数目备注: DrawPixelint x int y --绘制像素点x yvoid CPolygon_ConversionViewActive_Edge_Table_Conersionint Vertices2 int VertexNum return;完成有效边表转换算法并
void CPolygon_ConversionView::Active_Edge_Table_Conersion(int Vertices[][2], int VertexNum) { // 定义活化边表和扫描线 vector<Edge*> AET; int scanLine = Vertices[0][1];
// 初始化活化边表
for (int i = 0; i < VertexNum; i++) {
Edge* e = new Edge();
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) { // 保证 e->y1 < e->y2
swap(x1, x2);
swap(y1, y2);
}
// 计算斜率和截距
e->k = float(x2 - x1) / float(y2 - y1);
e->b = x1 - e->k * y1;
e->y1 = y1;
e->y2 = y2;
AET.push_back(e);
}
}
// 按 y 坐标排序
sort(AET.begin(), AET.end(), EdgeSort);
// 循环处理每一行扫描线
while (!AET.empty()) {
// 从活化边表中删除 y2 <= scanLine 的边
for (auto iter = AET.begin(); iter != AET.end();) {
if ((*iter)->y2 <= scanLine) {
delete (*iter);
iter = AET.erase(iter);
} else {
iter++;
}
}
// 将 AET 中的边按 x 坐标排序
sort(AET.begin(), AET.end(), EdgeXSort);
// 绘制每一对相邻交点之间的像素
for (int i = 0; i < AET.size(); i += 2) {
int x1 = ceil(AET[i]->x);
int x2 = floor(AET[i + 1]->x);
for (int x = x1; x <= x2; x++) {
DrawPixel(x, scanLine);
}
// 更新每条边的 x 坐标
AET[i]->x += AET[i]->k;
AET[i + 1]->x += AET[i + 1]->k;
}
// 更新扫描线的 y 坐标
scanLine++;
// 将新边插入 AET
for (auto iter = AET.begin(); iter != AET.end();) {
Edge* e = (*iter);
if (e->y1 == scanLine) {
iter = AET.erase(iter);
continue;
}
e->x = e->k * scanLine + e->b;
iter++;
}
for (int i = 0; i < VertexNum; i++) {
int y1 = Vertices[i][1];
int y2 = Vertices[(i + 1) % VertexNum][1];
if (y1 != y2 && y1 == scanLine) {
Edge* e = new Edge();
int x1 = Vertices[i][0];
int x2 = Vertices[(i + 1) % VertexNum][0];
if (y1 > y2) {
swap(x1, x2);
swap(y1, y2);
}
e->k = float(x2 - x1) / float(y2 - y1);
e->b = x1 - e->k * y1;
e->y1 = y1;
e->y2 = y2;
e->x = e->k * scanLine + e->b;
AET.push_back(e);
}
}
sort(AET.begin(), AET.end(), EdgeSort);
}
}
// 活化边表排序函数,按 y1 坐标升序排序 bool EdgeSort(Edge* e1, Edge* e2) { return e1->y1 < e2->y1; }
// 活化边表排序函数,按 x 坐标升序排序 bool EdgeXSort(Edge* e1, Edge* e2) { return e1->x < e2->x; }
// 绘制像素点函数,略
原文地址: http://www.cveoy.top/t/topic/bd4t 著作权归作者所有。请勿转载和采集!