【CG】三角形的光栅化

【CG】三角形的光栅化

@(CG)

三角形的光栅化的方法有:
- Edge-walking
- Edge-equation
- Barycentric-coordinate based

本文使用的方法是第二种方法:Edge-equation

算法的基本步骤
step

解释
1. 计算三条边的一般式方程。
2. 将三条边“中心化”,即使三角形中的任意一个点代入3条曲线,都会使Ax+By+C的结果都大于0。方法是将决定直线的两个点外的第三个点代入到直线方程,若结果小于0,则将参数A、B、C都乘以-1。
3. 计算三角形的外接矩形。
4. 遍历外接矩形中的每一个点,用得到的3条边的方程判断点在不在三角形中,如果在就画出该点。

我的test代码如下:

#include <iostream>
#include <vector>
#include <math.h>

using namespace std;

vector<int> lineEquation(int x1, int y1, int x2, int y2) {
    // line equation: Ax+ By+ C= 0
    vector<int> res;
    int A= y2- y1;
    int B= x1- x2;
    int C= x2* y1- x1* y2;
    res.push_back(A);
    res.push_back(B);
    res.push_back(C);
    return res;
}

vector<int> rasterizeTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
    int max_x= max(x1, max(x2, x3));
    int min_x= min(x1, min(x2, x3));
    int max_y= max(y1, max(y2, y3));
    int min_y= min(y1, min(y2, y3));
    int center_x= (max_x- min_x)/ 2;
    int center_y= (max_y- min_y)/ 2;
    vector< vector<int> > lines;
    lines.push_back(lineEquation(x1, y1, x2, y2));
    lines.push_back(lineEquation(x1, y1, x3, y3));
    lines.push_back(lineEquation(x3, y3, x2, y2));
    // centerlize the equations
    for (int i= 0; i< 3; i++) {
        int x_temp, y_temp;
        if (i== 0) {
            x_temp= x3; y_temp= y3;
        } else if (i== 1) {
            x_temp= x2; y_temp= y2;
        } else {
            x_temp= x1; y_temp= y1;
        }
        // A*x+ B*y+ C
        if (lines[i][0]* x_temp+ lines[i][1]* y_temp+ lines[i][2]< 0) {
            for (int j= 0; j< lines[i].size(); j++) {
                lines[i][j]*= -1;
            }
        }
    }
    // set pixel
    vector<int> pixels;
    for (int x= min_x; x<= max_x; x++) {
        for (int y= min_y; y<= max_y; y++) {
            bool isInside= true;
            for (int i= 0; i< 3; i++) {
                if (lines[i][0]* x+ lines[i][1]* y+ lines[i][2]< 0) {
                    isInside= false;
                    break;
                }
            }
            if (isInside) {
                pixels.push_back(x);
                pixels.push_back(y);
            }
        }
    }
    return pixels;
}

int main() {
    vector<int> test= rasterizeTriangle(0, 180, 300, -200, -300, -200);
    cout<< test.size()<< endl;
}

将test代码整合到Opengl3.3+ IMGUI中,能够得到如下结果:
Test

完整的代码还整合了bresenham算法画直线和圆,并用IMGUI改变圆的半径大小,参考我的另外一篇blog:
https://blog.csdn.net/timso1997/article/details/79732503

完整的代码参考我的github:
https://github.com/sysuts13/CG/tree/master/Opengl3_IMGUI_Bresenham-%20TriangleRas

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值