1. 程式人生 > 其它 >Cohen-Sutherland演算法的openGL實現

Cohen-Sutherland演算法的openGL實現

Cohen-Sutherland演算法的openGL實現

用的VC6這個老古董,新版本可能會跑不動(

#include "stdafx.h"
#include <GL/glut.h>
#include <cstdio>



#define LEFT 1//0001
#define RIGHT 2//0010
#define BOTTOM 4//0100
#define TOP 8//1000

struct Point{
	int x, y;
}point[2],initp[2];
struct Rectangle {
	int xmin,ymin,xmax,ymax;
}rec;

void mydisplay();
void init();
void myReshape(int w,int h);
int enCode(Point p);
void fuck();

void mydisplay();

void init(){
	printf("是否選擇預設座標?\n");
	printf("使用預設座標請輸入1\n");
	printf("自定義座標請輸入任意數字\n");
	int op;
	scanf("%d",&op);
	if(op == 1) {
		point[0].x = 150;
		point[0].y = 50;
		point[1].x = 50;
		point[1].y = 250;
		rec.xmin = 100;
		rec.xmax = 300;
		rec.ymin = 100;
		rec.ymax = 200;
		return;
	}

	printf("請輸入直線段端點座標\n");
	scanf("%d%d%d%d",&point[0].x,&point[0].y,&point[1].x,&point[1].y);
	printf("請輸入矩形框對角線座標");
	scanf("%d%d%d%d",&rec.xmin,&rec.ymin,&rec.xmax,&rec.ymax);
	return;
}
	

void myReshape (GLsizei w, GLsizei h)
{
	if(h == 0)
		h = 1;
	// 設定視區尺寸
	glViewport(0, 0, w, h);
	
	// 重置座標系統
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	
	//建立修剪空間的範圍
	if (w <= h) 
		glOrtho(0.0f, 250.0f, 0.0f, 250.0f*h/w, 1.0, -1.0);
	else
		glOrtho(0.0f, 250.0f*w/h, 0.0f, 250.0f, 1.0, -1.0);
}
int enCode(Point p){
	int ans = 0;
	if(p.x < rec.xmin) ans |= LEFT;
	else if(p.x > rec.xmax) ans |= RIGHT;
	if(p.y < rec.ymin) ans |= BOTTOM;
	else if(p.y > rec.ymax) ans |= TOP;
	return ans;
}
void fuck(){
	int x,y;
	int code1 = enCode(point[0]);
	int code2 = enCode(point[1]);
	int code = 0;
	while(code1 || code2) {
		if(code1 & code2) {
			break;
		}
		if(code1) code = code1;
		else code = code2;
		
		if(code & LEFT) {
			x = rec.xmin;
			y = point[0].y + (point[1].y - point[0].y) *
			(rec.xmin - point[0].x) / (point[1].x - point[0].x);
		}else if(code & RIGHT) {
			x = rec.xmax;
			y = point[0].y + (point[1].y - point[0].y) *
			(rec.xmax - point[0].x) / (point[1].x - point[0].x);
		}else if(code & BOTTOM) {
			y = rec.ymin;
			x = point[0].x + (point[1].x - point[0].x) *
			(rec.ymin - point[0].y) / (point[1].y - point[0].y);
		}else if(code & TOP) {
			y = rec.ymax;
			x = point[0].x + (point[1].x - point[0].x) *
			(rec.ymax - point[0].y) / (point[1].y - point[0].y);
		}
		if(code == code1) {
			point[0].x = x;
			point[0].y = y;
			code1 = enCode(point[0]);
		}else {
			point[1].x = x;
			point[1].y = y;
			code2 = enCode(point[1]);
		}
		
	}

}

void mydisplay(){
	initp[0] = point[0];
	initp[1] = point[1];
	fuck();// deal with point[0] point[1]
	
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1,0,0);
	glPointSize(2);
	glBegin(GL_LINE_LOOP);
	glVertex2i(rec.xmin, rec.ymin);//繪製矩形
	glVertex2i(rec.xmin, rec.ymax);
	glVertex2i(rec.xmax, rec.ymax);
	glVertex2i(rec.xmax, rec.ymin);
	glEnd();
	glColor3f(0,0,0);
	glLineWidth(3);
	glBegin(GL_LINES);
	glVertex2i(initp[0].x, initp[0].y);
	glVertex2i(initp[1].x, initp[1].y);
	glEnd();
	//glFlush();
	
	glColor3f(0.5,0.5,0);
	glBegin(GL_LINES);
	glVertex2i(point[0].x,point[0].y);
	glVertex2i(point[1].x,point[1].y);
	glEnd();
	glFlush();

	
	
}

int main(int argc, char *argv[])
{
	init();
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
	glutInitWindowPosition(500, 100);
	glutInitWindowSize(500, 400);
	glutCreateWindow("Cohen-Sutherland裁剪演算法");
	glClearColor(0.0, 0.0, 1.0, 0.0);
	glutReshapeFunc(myReshape);
	glutDisplayFunc(&mydisplay);
	//glutIdleFunc(&mydisplay);
	glutMainLoop();
	return 0;
}