opengl 直线裁剪Cohen-Sutherland算法

#include<Gl/glut.h>
#include <process.h>

class wcPt2D {
public:
    float x, y;
};

GLubyte encode(wcPt2D pt, wcPt2D winMin, wcPt2D winMax);

void swapPts(wcPt2D *p1, wcPt2D *p2);

void swapCodes(GLubyte *c1, GLubyte *c2);

void lineClipCohSuth(wcPt2D winMin, wcPt2D winMax, wcPt2D p1, wcPt2D p2);

void myKeyBoard(unsigned char key, int x, int y);

const GLint winLeftBitCode = 0x1;
const GLint winRightBitCode = 0x2;
const GLint winBottomBitCode = 0x4;
const GLint winTopBitCode = 0x8;

inline GLint inside(GLint code) {
    return GLint(!code);
}

inline GLint reject(GLint code1, GLint code2) {
    return GLint(code1 & code2);
}

inline GLint accept(GLint code1, GLint code2) {
    return GLint(!(code1 | code2));
}

GLubyte encode(wcPt2D pt, wcPt2D winMin, wcPt2D winMax) {
    GLubyte code = 0x00;
    if (pt.x < winMin.x) code = code | winLeftBitCode;
    if (pt.x > winMax.x) code = code | winRightBitCode;
    if (pt.y < winMin.y) code = code | winBottomBitCode;
    if (pt.y > winMax.y) code = code | winTopBitCode;
    return (code);
}

void swapPts(wcPt2D *p1, wcPt2D *p2) {
    wcPt2D tmp;
    tmp = *p1;
    *p1 = *p2;
    *p2 = tmp;
}

void swapCodes(GLubyte *c1, GLubyte *c2) {
    GLubyte tmp;
    tmp = *c1;
    *c1 = *c2;
    *c2 = tmp;
}

void lineClipCohSuth(wcPt2D winMin, wcPt2D winMax, wcPt2D p1, wcPt2D p2) {
    GLubyte code1, code2;
    GLint done = false, plotLine = false;
    GLfloat m;
    while (!done) {
        code1 = encode(p1, winMin, winMax);
        code2 = encode(p2, winMin, winMax);
        if (accept(code1, code2)) {
            done = true;
            plotLine = true;
        } else if (reject(code1, code2)) {
            done = true;
        } else {
            if (inside(code1)) {
                swapPts(&p1, &p2);
                swapCodes(&code1, &code2);
            }
            if (p2.x != p1.x) m = (p2.y - p1.y) / (p2.x - p1.x);
            if (code1 & winLeftBitCode) {
                p1.y += (winMin.x - p1.x) * m;
                p1.x = winMin.x;
            } else if (code1 & winRightBitCode) {
                p1.y += (winMax.x - p1.x) * m;
                p1.x = winMax.x;
            } else if (code1 & winBottomBitCode) {
                if (p2.x != p1.x)
                    p1.x += (winMin.y - p1.y) / m;
                p1.y = winMin.y;
            } else if (code1 & winTopBitCode) {
                if (p2.x != p1.x)
                    p1.x = (winMax.y - p1.y) / m;
                p1.y = winMax.y;
            }
        }
    }
    if (plotLine)
        glBegin(GL_LINES);
    glLineWidth(10);
    glColor3f(1, 0, 0);
    glVertex2f(p1.x, p1.y);
    glVertex2f(p2.x, p2.y);
    glEnd();
}

void drawpolygon(double cd[]) {
    glBegin(GL_LINE_LOOP);
    glLineWidth(10);
    for (int i = 0; i < 8; i = i + 2) {
        glVertex2f(cd[i], cd[i + 1]);
    }
    glEnd();
}

void drawline(double cd[]) {
    glBegin(GL_LINES);
    glLineWidth(10);
    for (int i = 0; i < 8; i = i + 2) {
        glVertex2f(cd[i], cd[i + 1]);
    }
    glEnd();
}

void myKeyBoard(unsigned char key, int x, int y) {
    wcPt2D winMin = {100, 100};
    wcPt2D winMax = {400, 400};
    wcPt2D p1 = {0, 0};
    wcPt2D p2 = {500, 500};


    wcPt2D p11 = {200, 300};
    wcPt2D p21 = {300, 200};

    wcPt2D p12 = {10, 50};
    wcPt2D p22 = {50, 10};
    if (key == 13) {
        lineClipCohSuth(winMin, winMax, p1, p2);
        lineClipCohSuth(winMin, winMax, p11, p21);
        lineClipCohSuth(winMin, winMax, p12, p22);

    }
    glFlush();
    if (key == 27)
        exit(0);
}

void display(void) {
    double cd[8] = {100, 100, 100, 400, 400, 400, 400, 100};
    double line[4] = {0, 0, 500, 500};
    double line1[4] = {200, 300, 300, 200};
    double line2[4] = {10, 50, 50, 10};
    glClear(GL_COLOR_BUFFER_BIT);
    glViewport(0, 0, 500, 500);
    glColor3f(0, 0, 0);
    drawpolygon(cd);
    drawline(line);
    drawline(line1);
    drawline(line2);
    glFlush();
}

int main(int argc, char **argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RED);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("Cohen-Sutherland");
    glClearColor(1, 1, 1, 0.0);
    glMatrixMode(GL_PROJECTION);//投影模型
    gluOrtho2D(0.0, 500.0, 0.0, 500.0);
    glutKeyboardFunc(myKeyBoard);
    glutDisplayFunc(display);
    glutMainLoop();
    return 0;

}

说明:
第一步:创建裁剪区域
第二步: 创建3条直线,一个穿过裁剪区域,一个在裁剪区域内,一个在裁剪区域外。
第三部:注册键盘事件,即回车调用裁剪函数,裁剪部分转换为红色。

效果图:
这里写图片描述
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值