void saomiaoxian_150802202023(Vec2i t0, Vec2i t1, Vec2i t2, TGAImage& image, TGAColor color) {
if (t0.y == t1.y && t0.y == t2.y) return; // 如果三个点的 y 坐标相等,则返回,不需要绘制该三角形
if (t0.y > t1.y) std::swap(t0, t1); // 确保 t0 的 y 坐标是三个点中最小的
if (t0.y > t2.y) std::swap(t0, t2); // 确保 t0 的 y 坐标是三个点中最小的
if (t1.y > t2.y) std::swap(t1, t2); // 确保 t2 的 y 坐标是三个点中最大的
int total_height = t2.y - t0.y; // 计算三角形的高度
for (int i = 0; i < total_height; i++) { // 对于每一行
bool second_half = i > t1.y - t0.y || t1.y == t0.y; // 判断该行是否在上半部分(第一次循环)还是下半部分(第二次循环)
int segment_height = second_half ? t2.y - t1.y : t1.y - t0.y; // 计算上半部分或下半部分的高度
float alpha = (float)i / total_height; // 计算当前行在三角形中的位置
float beta = (float)(i - (second_half ? t1.y - t0.y : 0)) / segment_height; // 计算当前行在上半部分或下半部分的位置
Vec2i A = t0 + (t2 - t0) * alpha; // 计算该行与左边交点的坐标
Vec2i B = second_half ? t1 + (t2 - t1) * beta : t0 + (t1 - t0) * beta; // 计算该行与右边交点的坐标
if (A.x > B.x) std::swap(A, B); // 确保左边交点在右边交点的左侧
for (int j = A.x; j <= B.x; j++) { // 在交点之间填充像素
image.set(j, t0.y + i, color); // 根据交点和当前行的位置计算像素坐标,并填充像素
}
}
}
if (t0.y == t1.y && t0.y == t2.y) return;:首先判断三个顶点的 y 坐标是否相等,如果相等则返回,因为这种情况下不能构成三角形。
if (t0.y > t1.y) std::swap(t0, t1); if (t0.y > t2.y) std::swap(t0, t2); if (t1.y > t2.y) std::swap(t1, t2);:对三个顶点按照 y 坐标从小到大排序,以 t0 为最上面的点,t2 为最下面的点。
int total_height = t2.y - t0.y;:计算三角形的高度,即最下面的点的 y 坐标减去最上面的点的 y 坐标。
for (int i = 0; i < total_height; i++) {:从上到下遍历每一行像素,循环次数等于三角形的高度。
bool second_half = i > t1.y - t0.y || t1.y == t0.y;:判断当前行是在三角形的上半部分还是下半部分。如果当前行高度已经超过 t1 和 t0 之间的高度或者 t0 和 t1 在同一水平线上,则表示当前行在下半部分。
int segment_height = second_half ? t2.y - t1.y : t1.y - t0.y;:计算当前行在三角形中的高度,如果在下半部分,则是 t2 和 t1 之间的高度,否则是 t1 和 t0 之间的高度。
float alpha = (float)i / total_height;:计算当前行在三角形中的纵向位置占整个三角形高度的比例。
float beta = (float)(i - (second_half ? t1.y - t0.y : 0)) / segment_height;:计算当前行在三角形中横向位置的比例。在下半部分时,当前行要减去 t1 和 t0 之间的高度,以确定在 t2 和 t1 这一边的位置。
Vec2i A = t0 + (t2 - t0) * alpha; Vec2i B = second_half ? t1 + (t2 - t1) * beta : t0 + (t1 - t0) * beta;:根据纵向位置比例 alpha 和横向位置比例 beta,计算当前行与三角形两侧的交点 A 和 B。
if (A.x > B.x) std::swap(A, B);:将交点 A 和 B 按照 x 坐标从小到大排序。
for (int j = A.x; j <= B.x; j++) { image.set(j, t0.y + i, color); 根据交点和当前行的位置计算像素坐标,并填充像素