功能:有效边表转换算法 参数说明: 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)
{
//1.构造活性边表
vector<vector
if (y1 == y2) continue; //忽略水平边
ActiveEdge edge;
if (y1 > y2) //下端点在后面
{
edge.X = x2;
edge.Dx = (float)(x1 - x2) / (float)(y1 - y2);
edge.Ymax = y1;
}
else //下端点在前面
{
edge.X = x1;
edge.Dx = (float)(x2 - x1) / (float)(y2 - y1);
edge.Ymax = y2;
}
AET[min(y1, y2)].push_back(edge);
}
//2.填充像素
vector<ActiveEdge> NET; //新边表
int scanLine = Vertices[0][1]; //扫描线
while (!AET.empty() || !NET.empty())
{
//2.1 将新边表中的边插入到活性边表中
for (auto it = NET.begin(); it != NET.end();)
{
AET[it->Ymax - scanLine].push_back(*it);
it = NET.erase(it);
}
//2.2 按照X值排序
for (auto& edges : AET)
{
sort(edges.begin(), edges.end(), [](const ActiveEdge& a, const ActiveEdge& b) {
return a.X < b.X;
});
}
//2.3 填充扫描线上的像素
for (auto& edges : AET)
{
for (int i = 0; i < (int)edges.size(); i += 2)
{
int x1 = ceil(edges[i].X);
int x2 = floor(edges[i + 1].X);
if (x1 <= x2)
{
for (int x = x1; x <= x2; x++)
{
DrawPixel(x, scanLine);
}
}
}
//2.4 更新X值
for (auto& edge : edges)
{
edge.X += edge.Dx;
}
//2.5 删除Ymax <= scanLine的边
edges.erase(remove_if(edges.begin(), edges.end(), [scanLine](const ActiveEdge& edge) {
return edge.Ymax <= scanLine;
}), edges.end());
}
//2.6 扫描线+1
scanLine++;
//2.7 更新新边表
for (auto& edges : AET)
{
for (auto& edge : edges)
{
if (edge.Ymax == scanLine)
{
NET.push_back(edge);
}
}
}
//2.8 删除活性边表中所有的空链表
AET.erase(remove_if(AET.begin(), AET.end(), [](const vector<ActiveEdge>& edges) {
return edges.empty();
}), AET.end());
}
}
原文地址: https://www.cveoy.top/t/topic/bedh 著作权归作者所有。请勿转载和采集!