计算机图形学(3.3)——编码裁剪算法实现

继续接着上一篇的。

修改后的编码裁剪算法的运行结果如下:
计算机图形学(3.3)——编码裁剪算法实现

裁剪后:

计算机图形学(3.3)——编码裁剪算法实现

裁剪成功!

(2)实现梁友栋裁剪算法

代码如下:

// CG_4_Liang-Barsky参数化裁剪算法.cpp : 定义控制台应用程序的入口点。

//

 

#include "stdafx.h"

#include "stdafx.h"

#include <GL/glut.h>

#include <stdio.h>

#include <stdlib.h>

int clipTest(float p,float q,float *u1,float *u2);

float x1,y1,x2,y2;

struct Rectangle

{

float XL,XR,YB,YT;

};

Rectangle rect;

void LineGL(int x0,int y0,int x1,int y1)

{

glBegin (GL_LINES);

glColor3f (1.0f, 0.0f, 0.0f); glVertex2f (x0,y0);

glColor3f (0.0f, 1.0f, 0.0f); glVertex2f (x1,y1);

glEnd ();

}

 

//x1,y1,x2,y2为直线端点坐标 XL,XR,YB,YT为窗口边界信息

int L_B_LineClip(Rectangle rect,float &x1,float &y1,float &x2,float &y2){

float u1=0,u2=1,dx=x2-x1,dy;

//u1为始点参数,初值为0u2为终点参数,初值为1

if(clipTest(-dx,x1-rect.XL,&u1,&u2))//计算左边界交点参数,更新u1u2

if(clipTest(dx,rect.XR-x1,&u1,&u2)){//计算右边界交点参数,更新u1u2

dy=y2-y1;

if(clipTest(-dy,y1-rect.YB,&u1,&u2))//计算下边界交点参数,更新u1u2

if(clipTest(dy,rect.YT-y1,&u1,&u2)){//计算上边界交点参数,更新u1u2

if(u2<1){

   x2=x1+u2*dx;//根据u2计算终点坐标

   y2=y1+u2*dy;

    }

    if(u1>0){

   x1+=u1*dx;//根据u1计算始点坐标

   y1+=u1*dy;

    }

    return 1;

    }

}

x1=y1=x2=y2=0;

LineGL(x1,y1,x2,y2);

return 0;

}

int clipTest(float p,float q,float *u1,float *u2){

float r;

int retVal=1;

if(p<0){

r=q/p;

if(r>*u2)   retVal=0;

else if(r>*u1) *u1=r;

}

else if(p>0){

r=q/p;

if(r<*u1) retVal=0;

else if(r<*u2) *u2=r;

}

else if(q<0) retVal=0;

return retVal;

}

 

void myDisplay()

{

glClear(GL_COLOR_BUFFER_BIT);

glColor3f (1.0f, 0.0f, 0.0f);

glRectf(rect.XL,rect.YB,rect.XR,rect.YT);

LineGL(x1,y1,x2,y2);

glFlush();

}

 

void Init()

{

glClearColor(0.0, 0.0, 0.0, 0.0);

glShadeModel(GL_FLAT);

rect.XL=100;

rect.XR=300;

rect.YB=100;

rect.YT=300;

x1 = 450,y1 = 0, x2 = 0, y2 = 450;

printf("Press key 'c' to Clip!\nPress key 'r' to Restore!\n");

}

 

void Reshape(int w, int h)

{

glViewport(0, 0, (GLsizei) w, (GLsizei) h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);

}

 

void keyboard(unsigned char key, int x, int y)

{

switch (key){

case 'c': L_B_LineClip(rect, x1,y1,x2,y2);

  glutPostRedisplay();break;

case 'r':Init();

  glutPostRedisplay();break;

case 'x':exit(0);break;

default:break;

}

}

 

int main(int argc, char *argv[])

{

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);

glutInitWindowPosition(100, 100);

glutInitWindowSize(640, 480);

glutCreateWindow("Hello World!");

Init();

glutDisplayFunc(myDisplay);

glutReshapeFunc(Reshape);

glutKeyboardFunc(keyboard);

glutMainLoop();

return 0;

}