计算机图形学-Code 1

版权声明:本文为博主原创文章,欢迎转载,转载请贴上博客地址 http://blog.csdn.net/xdg_blog https://blog.csdn.net/xdg_blog/article/details/52848995
/*------------------------------------
author:XD_G
location:SWUN
time:09/2015~01/2016
course:Computer Graphics
teacher:Tianyun Huang
如果认识黄天云老师,请代我向他问好!
------------------------------------*/

#include <iostream>
#include <vector>
#include <GL/glut.h>

#pragma comment( lib , "opengl32.lib")
#pragma comment( lib , "glu32.lib" )
#pragma comment( lib , "glut32.lib" )

#define x_min View_leftbottom.x
#define x_max View_righttop.x
#define y_min View_leftbottom.y
#define y_max View_righttop.y

using namespace std;

//point struct
class Point {       
public:
    int x;
    int y;
    unsigned char loc;
    Point() :x(0), y(0), loc(0) {}
    Point(int  a, int  b) :x(a), y(b), loc(0) {}
    Point(int  a, int  b, unsigned char c) :x(a), y(b), loc(c) {}
    Point(const Point& src): x(src.x),y(src.y),loc(src.loc) {}
    Point& operator=(const Point &src) {
        if (this != &src) {
            this->x = src.x;
            this->y = src.y;
            this->loc = src.loc;
        }
        return *this;
    }
};

enum Wnd{LEFT, RIGHT, BOTTOM, TOP};

//windows_size
int L_w = 1366 / 2;
int L_h = 768 / 2;

//view_windows
Point View_leftbottom(-L_w, -L_h);
Point View_righttop(L_w, L_h);

//lines_set
vector<Point >  line_points_set;
vector<Point >  new_line_points_set;

//polygon_polygon_points_set
vector<Point >  polygon_points_set;

//color table
GLfloat black_color[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat red_color[] = { 1.0,0.0,0.0,1.0 };
GLfloat green_color[] = { 0.0, 1.0, 0.0, 1.0 };
GLfloat blue_color[] = { 0.0, 0.0, 1.0, 1.0 };
GLfloat white_color[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat grey_color[] = { 0.5, 0.5, 0.5, 1.0 };

//clip area_code 
const unsigned char winLeftBitCode = 0x1;// 0001
const unsigned char winRightBitCode = 0x2;// 0010
const unsigned char winBottomBitCode = 0x4;// 0100
const unsigned char winTopBitCode = 0x8;// 1000

//Functions
//Init & Set func
inline void setPixel(int x, int y, GLfloat* c){
    glColor4fv(c);
    glBegin(GL_POINTS);
    glVertex2i(x, y);
    glEnd();
}

//将所求直线变换到斜率0~1之间
inline void translate(int &x0, int &y0, int &x1, int &y1, float k) {
    if (k > 1) {
        int temp = x0;
        x0 = y0;
        y0 = temp;
        temp = x1;
        x1 = y1;
        y1 = temp;
        if (x0 > x1) {
            temp = x0;
            x0 = x1;
            x1 = temp;
            temp = y0;
            y0 = y1;
            y1 = temp;
        }
    }
    else if (k >= -1 && k < 0) {
        y0 = -y0;
        y1 = -y1;
        if (x0 > x1) {
            int temp = x0;
            x0 = x1;
            x1 = temp;
            temp = y0;
            y0 = y1;
            y1 = temp;
        }
    }
    else if (k < -1) {
        int temp = x0;
        x0 = y0;
        y0 = -temp;
        temp = x1;
        x1 = y1;
        y1 = -temp;
        if (x0 > x1) {
            temp = x0;
            x0 = x1;
            x1 = temp;
            temp = y0;
            y0 = y1;
            y1 = temp;
        }
    }
    else {
        if (x0 > x1) {
            int temp = x0;
            x0 = x1;
            x1 = temp;
            temp = y0;
            y0 = y1;
            y1 = temp;
        }
    }
}

//对称作直线时将生成直线逆向还原到所求
inline void set_line_pixel(int x, int y, float k, GLfloat* color) {
    if (k > 0 && k <= 1)
        setPixel(x, y, color);
    if (k > 1)
        setPixel(y, x, color);
    if (k >= -1 && k < 0)
        setPixel(x, -y, color);
    if (k < -1)
        setPixel(-y, x, color);
}

//从八分圆对称做出完整圆
inline void circlePoint(int x, int y, GLfloat* color){
    setPixel(x, y, color);
    setPixel(y, x, color);
    setPixel(-x, y, color);
    setPixel(y, -x, color);
    setPixel(x, -y, color);
    setPixel(-y, x, color);
    setPixel(-x, -y, color);
    setPixel(-y, -x, color);
}

//设置多边形顶点集合
void polygon_points() {
    Point A(-290, 150);
    Point B(-30, 80);
    Point C(210, 260);
    Point D(250, -55);
    Point E(30, -245);
    Point F(10, -230);
    polygon_points_set.push_back(A);
    polygon_points_set.push_back(B);
    polygon_points_set.push_back(C);
    polygon_points_set.push_back(D);
    polygon_points_set.push_back(E);
    polygon_points_set.push_back(F);
}

//设置线段端点集合
void line_points() {
    Point A(-290, 50);  Point B(10, -130);
    Point C(70, 15);    Point D(-45, -255);
    Point E(30, 210);   Point F(26, -280);
    Point G(30, 15);    Point H(180, 80);
    Point I(50, -250);  Point J(50, 250);
    Point K(-250, 50);  Point L(250, 50);
    line_points_set.push_back(A);
    line_points_set.push_back(B);
    line_points_set.push_back(C);
    line_points_set.push_back(D);
    line_points_set.push_back(E);
    line_points_set.push_back(F);
    line_points_set.push_back(G);
    line_points_set.push_back(H);
    line_points_set.push_back(I);
    line_points_set.push_back(J);
    line_points_set.push_back(K);
    line_points_set.push_back(L);
}

//作直线
inline void GL_Line(int x0, int y0, int x1, int y1, GLfloat* color, int width = 1) {
    glColor4fv(color);
    glLineWidth(width);
    glBegin(GL_LINES);
    glVertex3f(x0, y0, 0.0f);
    glVertex3f(x1, y1, 0.0f);
    glEnd();
}

//作直线
inline void GL_Line(Point p1, Point p2, GLfloat* color, int width = 1) {
    glColor4fv(color);
    glLineWidth(width);
    glBegin(GL_LINES);
    glVertex3f(p1.x, p1.y, 0.0f);
    glVertex3f(p2.x, p2.y, 0.0f);
    glEnd();
}

//设置观察窗口大小
inline void set_ViewWindows(int xmin, int xmax, int ymin, int ymax) {
    x_min = xmin; x_max = xmax; y_min = ymin; y_max = ymax;
    GL_Line(x_min, y_min, x_min, y_max, grey_color);
    GL_Line(x_min, y_min, x_max, y_min, grey_color);
    GL_Line(x_max, y_min, x_max, y_max, grey_color);
    GL_Line(x_min, y_max, x_max, y_max, grey_color);
}
  
//Algorithms func

//DDA直线算法
void DDALine(int x0, int y0, int x1, int y1, GLfloat* color){
    int i;
    float dx, dy, length, x, y;
    if (fabs(x1*1.0 - x0) >= fabs(y1*1.0 - y0))
        length = fabs(x1*1.0 - x0);
    else
        length = fabs(y1*1.0 - y0);
    dx = (x1 - x0) / length;
    dy = (y1 - y0) / length;
    i = 1;
    x = x0;
    y = y0;
    while (i < length){
        setPixel(int(x + 0.5), int(y + 0.5), color);
        x = x + dx;
        y = y + dy;
        i++;
    }

}

//Bresenham直线算法(全斜率_对称)
void Bresenham_Line(int x0, int y0, int x1, int y1, GLfloat* color){
    float k = (y1 - y0) * 1.00 / (x1 - x0) * 1.00;
    translate(x0, y0, x1, y1, k);
    int dx, dy, e, i, x, y;
    dx = x1 - x0, dy = y1 - y0, e = 2 * dy - dx;
    x = x0, y = y0;
    for (i = 0; i <= dx; i++){
        set_line_pixel(x, y, k, color);
        x++;
        if (e >= 0){
            y++;
            e = e + 2 * dy - 2 * dx;
        }
        else{
            e = e + 2 * dy;
        }
    }
}

//中点画椭圆
void MidpointEllipse(int xc, int yc, int a, int b, GLfloat* color){
    long aa = a*a, bb = b*b;
    long twoaa = 2 * aa, twobb = 2 * bb;
    long x = 0, y = b;
    long long d;
    long dx = 0;
    long dy = twoaa * y;
    d = long(bb + aa*(-b + 0.25) + 0.5);
    setPixel(xc + x, yc + y, color);
    setPixel(xc + x, yc - y, color);
    setPixel(xc - x, yc + y, color);
    setPixel(xc - x, yc - y, color);
    while (dx < dy){
        x++;
        dx += twobb;
        if (d < 0)
            d += bb + dx;
        else{
            dy -= twoaa;
            d += bb + dx - dy;
            y--;
        }
        setPixel(xc + x, yc + y, color);
        setPixel(xc + x, yc - y, color);
        setPixel(xc - x, yc + y, color);
        setPixel(xc - x, yc - y, color);
    }
    d =long long( bb*(x + 0.5)*(x + 0.5) + aa*(y - 1)*(y - 1) - aa*bb + 0.5);
    cout << "X:" << x << endl;
    cout << "1:" << long long (bb*(x + 0.5)*(x + 0.5)) << endl;
    cout << "2:" << aa*(y - 1)*(y - 1) << endl;
    cout << "3:" << aa*bb << endl;
    cout << "D:" << d << endl;
    while (y > 0){
        y--;
        dy -= twoaa;
        if (d > 0)
            d += aa - dy;
        else{
            x++;
            dx += twobb;
            d += aa - dy + dx;
        }
        setPixel(xc + x, yc + y, color);
        setPixel(xc + x, yc - y, color);
        setPixel(xc - x, yc + y, color);
        setPixel(xc - x, yc - y, color);
    }
}

//中点画圆
void MidPointCircle(int r, GLfloat* color){
    int x, y;
    int e;
    x = 0;
    y = r;
    e = 1 - r;
    circlePoint(x, y, color);
    while (x <= y){
        x++;
        if (e < 0){
            e += 2 * x + 1;
        }
        else{
            y--;
            e += 2 * (x - y) + 1;
        }
        circlePoint(x, y, color);
    }
}

//中点画抛物线
//mode1:y=a*x^2+bx+c
//mode2:x=a*y^2+by+c
void MidPointParabola(float a, float b, float c, int mode, GLfloat* color) {
    int flag = 1;
    if (a < 0) {
        a = -a;
        b = -b;
        c = -c;
        flag = -1;
    }
    cout << a << endl;
    float px = -b / (2 * a);
    float py = (4 * a*c - b*b) / (4 * a);
    if (a == 0) {
        setPixel(0.0 + px, 0.0 + py, color);
        return;
    }
    float x = 0, y = 0;
    float e = 0;
    if (mode == 1) {
        setPixel(x + px, y + py, color);
        setPixel(-x + px, y + py, color);
    }
    else {
        setPixel(y + py, x + px, color);
        setPixel(y + py, -x + px, color);
    }

    while (x <= 1 / (2 * a)) {  //area_1

        if (e <= 0) {
            e += -(2 * x + 3) * a + 1;
            ++y;
        }
        else {
            e += -(2 * x + 3) * a;
        }
        if (mode == 1) {
            if (flag == 1) {
                setPixel(x + px, y + py, color);
                setPixel(-x + px, y + py, color);
            }
            else {
                setPixel(x + px, -y - py, color);
                setPixel(-x + px, -y - py, color);
            }
        }
        else {
            if (flag == 1) {
                setPixel(y + py, x + px, color);
                setPixel(y + py, -x + px, color);
            }
            else {
                setPixel(-y - py, x + px, color);
                setPixel(-y - py, -x + px, color);
            }
        }
        ++x;
    }
    x -= 1;//上句多加1

    e = (x + 0.5)*(x + 0.5)  * a - y - 1;
    while (x < 100) {//area_2
        if (e <= 0) {
            e += (2 * x + 2) * a - 1;
            x++;
        }
        else {
            e -= 1;

        }
        if (mode == 1) {
            if (flag == 1) {
                setPixel(x + px, y + py, color);
                setPixel(-x + px, y + py, color);
            }
            else {
                setPixel(x + px, -y - py, color);
                setPixel(-x + px, -y - py, color);
            }
        }
        else {
            if (flag == 1) {
                setPixel(y + py, x + px, color);
                setPixel(y + py, -x + px, color);
            }
            else {
                setPixel(-y - py, x + px, color);
                setPixel(-y - py, -x + px, color);
            }
        }
        y++;
    }
}

//中点画线
void MidPointLine(int x0, int y0, int x1, int y1, GLfloat* color) {
    float k = (y1 - y0)*1.00 / (x1 - x0)*1.00;
    translate(x0, y0, x1, y1, k);
    int dx = x1 - x0, dy = y1 - y0;
    float b = (dx*y1 - dy*x1) / dx;
    float d0 = dx*(y0 + 0.5) - dy*(x0 + 1) - dx*b;
    int x = x0, y = y0;
    double d = d0;
    while (x <= x1) {
        set_line_pixel(x, y, k, color);
        x++;
        if (d >= 0) {

            d = d - dy;
        }
        else {
            y++;
            d = d - dy + dx;
        }
    }
}
  
//通过顶点集合绘制多边形
void polygon(vector<Point>* set, GLfloat* color, int width = 1) {
    for (auto pr = set->begin() + 1; pr != set->end(); ++pr) {
        auto pl = pr - 1;
        GL_Line(pl->x, pl->y, pr->x, pr->y, color, width);
    }
    GL_Line((set->end() - 1)->x, (set->end() - 1)->y, set->begin()->x, set->begin()->y, color, width);
}

//将线段端点集合绘制成为线段
void lines(vector<Point>* set, GLfloat* color, int width = 1) {
    for (auto pr = set->begin() + 1; pr <= set->end() - 1; pr += 2) {
        auto pl = pr - 1;
        GL_Line(pl->x, pl->y, pr->x, pr->y, color, width);
        if (pr == set->end() - 1)
            break;
    }
}

//设置点的区域编码
void set_PointLoc(Point* pr) {
    pr->loc = 0;
    if (pr->x < x_min)
        pr->loc |= winLeftBitCode;
    if (pr->x > x_max)
        pr->loc |= winRightBitCode;
    if (pr->y < y_min)
        pr->loc |= winBottomBitCode;
    if (pr->y > y_max)
        pr->loc |= winTopBitCode;
}

//设置点集合的区域编码
void set_Loc(vector<Point>* set) {
    for (auto pr = set->begin(); pr < set->end(); ++pr)
        set_PointLoc(&*pr);
}

//交换两点坐标
void swapPoints(Point &p1, Point &p2) {
    Point _temp;
    _temp = p1;
    p1 = p2;
    p2 = _temp;
}

//判断点是否在窗口内
inline bool insideornot(Point p) {
    return !(p.loc);
}

//判断是否两点都在窗口外
inline unsigned char both_out(Point p1, Point p2) {
    return p1.loc & p2.loc;
}

//判断是否两点都在窗口内
inline unsigned char both_in(Point p1, Point p2) {
    return !(p1.loc | p2.loc);
}

//单条线段裁剪_CouhenSutherland
void LineClip_CouhenSutherland(Point p1, Point p2, GLfloat* color, int width = 1) {
    bool done = false, plot = false;
    double m = 0;
    if (p1.x != p2.x)
        m = (float)(p2.y - p1.y) / (float)(p2.x - p1.x);
    while (!done) {
        set_PointLoc(&p1);
        set_PointLoc(&p2);
        if (both_in(p1, p2)) {
            done = true;
            plot = true;
        }
        else if (both_out(p1, p2)) {
            done = true;
        }
        else {
            if (insideornot(p1)) {
                swapPoints(p1, p2);
            }
            if (p1.loc & winLeftBitCode) {
                p1.y += (x_min - p1.x)*m;
                p1.x = x_min;
            }
            else if (p1.loc & winRightBitCode) {
                p1.y += (x_max - p1.x)*m;
                p1.x = x_max;
            }
            else if (p1.loc & winBottomBitCode) {
                if (p2.x != p1.x)
                    p1.x += (y_min - p1.y) / m;
                p1.y = y_min;
            }
            else if (p1.loc & winTopBitCode) {
                if (p2.x != p1.x)
                    p1.x += (y_max - p1.y) / m;
                p1.y = y_max;
            }
        }
    }
    if (plot)
        GL_Line(p1.x, p1.y, p2.x, p2.y, color, width);
}

//线段集合裁剪_CouhenSutherland
void LineSetClip_CouhenSutherland(vector<Point>* set, GLfloat* color, int width = 1) {
    set_Loc(set);//设置线段端点区域码
    for (auto pr = set->begin() + 1; pr <= set->end() - 1; pr += 2) {
        auto pl = pr - 1;
        LineClip_CouhenSutherland(*pl, *pr, color, width);
        if (pr == set->end() - 1)
            break;
    }
}

//计算Liang算法中的p值
double calculate_pk(const Point p1, const Point p2, int type) {
    switch (type) {
    case 0:
        return -(p2.x - p1.x);
        break;
    case 1:
        return p2.x - p1.x;
        break;
    case 2:
        return -(p2.y - p1.y);
        break;
    case 3:
        return p2.y - p1.y;
        break;
    }
}

//计算Liang算法中的q值
double calculate_qk(const Point p1, const Point p2, int type) {
    switch (type) {
    case 0:
        return p1.x - x_min;
        break;
    case 1:
        return x_max - p1.x;
        break;
    case 2:
        return p1.y - y_min;
        break;
    case 3:
        return y_max - p1.y;
        break;
    }
}

bool LineClip_test(const double p, const double q, double &u1, double &u2) {
    double u = q / p;
    if (p < 0) {
        if (u > u2)
            return false;
        else if (u > u1) {
            u1 = u;
            return true;
        }
    }
    else if (p > 0) {
        if (u < u1)
            return false;
        else if (u < u2) {
            u2 = u;
            return true;
        }
    }

    else if (q < 0)
        return false;
}

//单条线段裁剪_LiangBarsky
void LineClip_LiangBarsky(Point p1, Point p2, GLfloat* color, int width = 1) {
    double u1 = 0, u2 = 1, u = 0;;
    int dx = p2.x - p1.x;
    int dy = p2.y - p1.y;

    vector<double > pk;
    vector<double > qk;
    for (int i = 0; i < 4; ++i) {
        double temp;
        temp = calculate_pk(p1, p2, i);
        pk.push_back(temp);
        temp = calculate_qk(p1, p2, i);
        qk.push_back(temp);
    }

    if (LineClip_test(pk[LEFT], qk[LEFT], u1, u2)) {
        if (LineClip_test(pk[RIGHT], qk[RIGHT], u1, u2)) {
            if (LineClip_test(pk[BOTTOM], qk[BOTTOM], u1, u2)) {
                if (LineClip_test(pk[TOP], qk[TOP], u1, u2)) {
                    if (u2 < 1) {
                        p2.x = p1.x + u2 * dx;
                        p2.y = p1.y + u2 * dy;
                    }
                    if (u1 > 0) {
                        p1.x = p1.x + u1 * dx;
                        p1.y = p1.y + u1 * dy;
                    }
                    GL_Line(p1.x, p1.y, p2.x, p2.y, color, width);
                }
            }
        }
    }
}

//线段集合裁剪_LiangBarsky
void LineSetClip_LiangBarsky(vector<Point>* set, GLfloat* color, int width = 1) {
    for (auto pr = set->begin() + 1; pr <= set->end() - 1; pr += 2) {
        auto pl = pr - 1;
        LineClip_LiangBarsky(*pl, *pr, color, width);
        if (pr == set->end() - 1)
            break;
    }
}

//判断点是否在边界内
bool isPointinsideEdge(Point p, const int mode) {
    set_PointLoc(&p);
    switch (mode) {
    case LEFT:
        if ((p.loc & winLeftBitCode) == winLeftBitCode)
            return false;
        else return true;
    case RIGHT:
        if ((p.loc & winRightBitCode) == winRightBitCode)
            return false;
        else return true;
    case BOTTOM:
        if ((p.loc & winBottomBitCode) == winBottomBitCode)
            return false;
        else return true;
    case TOP:
        if ((p.loc & winTopBitCode) == winTopBitCode)
            return false;
        else return true;
    }
}

//判断线段是否与边界相交
bool isLinecrossEdge(Point p1, Point p2, const int mode) {
    if (isPointinsideEdge(p1, mode) == isPointinsideEdge(p2, mode))
        return false;
    return true;
}

//计算线段与边界直线的交点
Point intersect(Point p1, Point p2, const int mode) {
    /*if (p1.x == p2.x)
        exit(0);*/
    Point result;

    switch (mode) {
    case LEFT:      
        result.x = x_min;
        result.y = p1.y + (x_min - p1.x) * (p2.y - p1.y) / (p2.x - p1.x);
        return result;
        break;
    case RIGHT:
        result.x = x_max;
        result.y = p1.y + (x_max - p1.x) * (p2.y - p1.y) / (p2.x - p1.x);
        return result;
        break;
    case BOTTOM:
        result.y = y_min;
        result.x = p1.x + (y_min - p1.y) / ((double)(p2.y - p1.y) / (double)(p2.x - p1.x));
        return result;
        break;
    case TOP:
        result.y = y_max;
        result.x = p1.x + (y_max - p1.y) / ((double)(p2.y - p1.y) / (double)(p2.x - p1.x));
        return result;
        break;
    }
}

//水平垂直情况下的线段顶点的添加
void parallelClip(Point p1, Point p2, vector<Point >* set, const int mode) {
    if (p1.x == p2.x) {//垂直
        switch (mode) {
        case LEFT:
            if (p1.x >= x_min)//II2
                set->push_back(p2);
            break;
        case RIGHT:
            if (p1.x <= x_max)//II2
                set->push_back(p2);
            break;
        case BOTTOM:
            if ((p1.y >= y_min) && (p2.y >= y_min))//II2
                set->push_back(p2);
            else if ((p1.y >= y_min) && (p2.y < y_min)) {//IOX
                Point temp(p1.x, y_min);
                set->push_back(temp);
            }
            else if ((p1.y < y_min) && (p2.y >= y_min)) {//OIX2
                Point temp(p1.x, y_min);
                set->push_back(temp);
                set->push_back(p2);
            }
            break;
        case TOP:
            if ((p1.y <= y_max) && (p2.y <= y_max))//II2
                set->push_back(p2);
            else if ((p1.y > y_max) && (p2.y <= y_max)) {//OIX2
                Point temp(p1.x, y_max);
                set->push_back(temp);
                set->push_back(p2);
            }
            else if ((p1.y <= y_max) && (p2.y > y_max)) {//IOX
                Point temp(p1.x, y_max);
                set->push_back(temp);
            }
            break;
        }
        return;
    }

    else if (p1.y == p2.y) {//水平
        switch (mode) {
        case LEFT:
            if ((p1.x >= x_min) && (p2.x >= x_min))//II2
                set->push_back(p2);
            else if ((p1.x < x_min) && (p2.x >= x_min)) {//OIX2
                Point temp(x_min, p1.y);
                set->push_back(temp);
                set->push_back(p2);
            }
            else if ((p1.x >= x_min) && (p2.x < x_min)) {//IOX
                set->push_back(p1);
                Point temp(x_min, p1.y);
                set->push_back(temp);
            }
            break;
        case RIGHT:
            if ((p1.x <= x_max) && (p2.x <= x_max))//II2
                set->push_back(p2);
            else if ((p1.x <= x_max) && (p2.x > x_max)) {//IOX
                set->push_back(p1);
                Point temp(x_max, p1.y);
                set->push_back(temp);
            }
            else if ((p1.x > x_max) && (p2.x <= x_max)) {//OIx2
                Point temp(x_max, p1.y);
                set->push_back(temp);
                set->push_back(p2);
            }
            break;
        case BOTTOM:
            if (p1.y >= y_min)//II2
                set->push_back(p2);
            break;
        case TOP:
            if (p1.y <= y_max)//II2
                set->push_back(p2);
            break;
        }
        return;
    }
}

//各种方向下多边形裁剪
void PolygonEdgeClip(vector<Point>* set, vector<Point>* newset, const int mode) {
    for (auto pl = set->begin(); pl != set->end(); ++pl) {
        if (pl == (set->end() - 1)) break;
        auto pr = pl + 1;
            if (isPointinsideEdge(*pl, mode)) {
            if (isPointinsideEdge(*pr, mode)) {//II2
                newset->push_back(*pr);
            }
            else {//IOX
                newset->push_back(intersect(*pl, *pr, mode));//

            }
        }
        else if (!isPointinsideEdge(*pl, mode)) {
            if (isPointinsideEdge(*pr, mode)) {//OIX2
                newset->push_back(intersect(*pl, *pr, mode));
                newset->push_back(*pr);
            }
        }
    }

    if (((set->end() - 1)->x == (set->begin())->x) || ((set->end() - 1)->y == (set->begin())->y))
        parallelClip(*(set->end() - 1), *(set->begin()), newset, mode);
    else if (isPointinsideEdge(*(set->end() - 1), mode)) {
        if (isPointinsideEdge(*(set->begin()), mode)) {//II2
            newset->push_back(*(set->begin()));
        }
        else if (!isPointinsideEdge(*(set->begin()), mode)) {//IOX
            newset->push_back(intersect(*(set->end() - 1), *(set->begin()), mode));//
        }
    }
    else if (!isPointinsideEdge(*(set->end() - 1), mode)) {
        if (isPointinsideEdge(*(set->begin()), mode)) {//OIX2
            newset->push_back(intersect(*(set->end() - 1), *(set->begin()), mode));
            newset->push_back(*(set->begin()));
        }
    }

}

//多边形裁剪
void PolygonClip(vector<Point>* set, GLfloat* color, int width = 1) {
    vector<Point > set_L, set_R, set_B, set_result;
    PolygonEdgeClip(set, &set_L, LEFT);//四个方向上各裁剪一次
    PolygonEdgeClip(&set_L, &set_R, RIGHT);
    PolygonEdgeClip(&set_R, &set_B, BOTTOM);
    PolygonEdgeClip(&set_B, &set_result, TOP);
    polygon(&set_result, color, 3);
}
  
//Frame func
void display(){
    glClear(GL_COLOR_BUFFER_BIT);
    DDALine(0,-L_h,0,L_h,black_color);//坐标轴
    DDALine(-L_w, 0, L_w, 0, black_color);

    /*----各种图形生成算法.start:----*/
    MidPointParabola(1.0000 / 50,1,2,1,blue_color); //中点画抛物线

    Bresenham_Line(180, -150, -350, 470, red_color);//全斜率直线

    MidPointCircle(175, green_color);//中点画圆

    MidpointEllipse(0, 0, 250, 140, black_color);//中点画椭圆

    MidPointLine(-110, 150, 350, 270, red_color);//中点画线
    /*----各种图形生成算法.end!----*/

    /*----线段裁剪.start:----*/
    line_points();//设置线段点集合
    lines(&line_points_set, green_color, 3);//画线
    set_ViewWindows(-200, 200, -200, 200);//设置窗口

    LineSetClip_CouhenSutherland(&line_points_set, red_color, 3);//Couhen_Sutherland线段裁剪

    LineSetClip_LiangBarsky(&line_points_set, red_color, 3);//LiangBarsky线段裁剪
    /*----线段裁剪.end!----*/

    /*----多边形裁剪.start:----*/
    polygon_points();//设置多边形顶点
    polygon(&polygon_points_set, green_color, 3);//绘制原始多边形
    set_ViewWindows(-200, 200, -200, 200);//设置窗口
    PolygonClip(&polygon_points_set, red_color, 3);//多边形裁剪
    /*----多边形裁剪.end!----*/

    glFlush();
}

//Display Init
void init(void){
    glClearColor(1.0, 1.0, 1.0, 0.0);//设置清屏颜色
    glMatrixMode(GL_PROJECTION);//设置投影矩阵
    glLoadIdentity();//单位化上述投影矩阵
    gluOrtho2D(-L_w*1.0, L_w*1.0, -L_h*1.0, L_h*1.0);//设置具体投影矩阵为平面正交投影4/3
}

void main(int argc, char** argv){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowPosition(50, 50);
    glutInitWindowSize(L_w*2, L_h*2);
    glutCreateWindow("Graphic Display");
    init();
    glutDisplayFunc(&display);
    glutMainLoop();
}
  

猜你喜欢

转载自blog.csdn.net/xdg_blog/article/details/52848995