三角形的三个顶点的颜色分别为红、绿、蓝,使用有效边表算法填充三角形的代码
时间: 2023-06-25 20:06:41 浏览: 84
以下是使用有效边表算法填充三角形的C++代码:
```c++
#include <iostream>
#include <vector>
#include <algorithm>
struct Point {
int x, y;
};
struct Edge {
int ymax; // 边的最大y值
float x; // 边与扫描线的交点x坐标的浮点数
float k; // 斜率
};
// 求两点之间的斜率
float getSlope(Point p1, Point p2) {
return static_cast<float>(p1.x - p2.x) / (p1.y - p2.y);
}
// 比较两条边的交点x坐标大小
bool cmp(const Edge& e1, const Edge& e2) {
return e1.x < e2.x;
}
int main() {
// 设置三角形的三个顶点
std::vector<Point> vertices { {100, 100}, {200, 300}, {300, 150} };
// 按照y坐标从小到大排序
std::sort(vertices.begin(), vertices.end(), [](const Point& p1, const Point& p2) { return p1.y < p2.y; });
// 初始化有效边表
std::vector<Edge> AET;
// 找出起始扫描线的y值和终止扫描线的y值
int ymin = vertices.front().y;
int ymax = vertices.back().y;
// 从起始扫描线开始向上扫描
for (int y = ymin; y <= ymax; ++y) {
// 从顶点集合中找出与当前扫描线有交点的边
std::vector<Edge> NET;
for (int i = 0; i < 3; ++i) {
int j = (i + 1) % 3;
if (vertices[i].y <= y && vertices[j].y > y) {
Edge e;
e.ymax = vertices[j].y;
e.x = vertices[i].x + getSlope(vertices[i], vertices[j]) * (y - vertices[i].y);
e.k = getSlope(vertices[i], vertices[j]);
NET.push_back(e);
}
}
// 将NET中的边按照交点x坐标排序,并依次加入AET中
std::sort(NET.begin(), NET.end(), cmp);
AET.insert(AET.end(), NET.begin(), NET.end());
// 从AET中删除ymax等于当前扫描线y的边
AET.erase(std::remove_if(AET.begin(), AET.end(), [y](const Edge& e) { return e.ymax == y; }), AET.end());
// 将AET中的边根据交点x坐标分为一组组,每一组对应一段需要填充颜色的区域
std::sort(AET.begin(), AET.end(), cmp);
for (int i = 0; i < AET.size(); i += 2) {
int x1 = static_cast<int>(AET[i].x);
int x2 = static_cast<int>(AET[i + 1].x);
for (int x = x1; x <= x2; ++x) {
// 在(x, y)处填充颜色
std::cout << "在(" << x << ", " << y << ")处填充颜色" << std::endl;
}
}
// 更新AET中每条边的交点x坐标
for (auto& e : AET) {
e.x += e.k;
}
}
return 0;
}
```
该算法的基本思想是,将三角形的三条边分别加入一个“边表”中,然后从起始扫描线开始向上扫描,每扫描到一条扫描线,将与该扫描线有交点的边从边表中取出,按照交点x坐标排序,并加入“有效边表”中。然后,从有效边表中删除ymax等于当前扫描线y的边,将有效边表中的边根据交点x坐标分成一组组,每一组对应一段需要填充颜色的区域,依次填充颜色即可。最后,更新有效边表中每条边的交点x坐标,并继续向上扫描。
阅读全文