计算机图形学(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为始点参数,初值为0,u2为终点参数,初值为1
if(clipTest(-dx,x1-rect.XL,&u1,&u2))//计算左边界交点参数,更新u1、u2
if(clipTest(dx,rect.XR-x1,&u1,&u2)){//计算右边界交点参数,更新u1、u2
dy=y2-y1;
if(clipTest(-dy,y1-rect.YB,&u1,&u2))//计算下边界交点参数,更新u1、u2
if(clipTest(dy,rect.YT-y1,&u1,&u2)){//计算上边界交点参数,更新u1、u2
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;
}