1. 程式人生 > >opengl實現cs、liang-barsky直線裁剪演算法

opengl實現cs、liang-barsky直線裁剪演算法

#include<glut.h>
#include<iostream>
#define L 00001
#define R 00002
#define B 00004
#define T 00010
#define M 00000

#define LT 00011
#define LB 00005
#define RT 00012
#define RB 00006
//#define L 0x0001
//#define R 0x0002
//#define B 0x0004
//#define T 0x0008
//#define M 0x0000
//
//#define LT 0x0009
//#define LB 0x0005
//#define RT 0x000a
//#define RB 0x0006
using namespace std;
struct rectan {
	int xx0, yy0;
	int xx1, yy1;
}rec;
int temX = 0, tempY = 0;
int c0 = 0, c1 = 0, c3 = 0;
bool f = false;

int CSLine(float xwl, float xwr, float ywb, float ywt, float x, float y) {   //得到編碼區
	int temp = 0;
	if (x < xwl) {
		temp |= L;
	}
	else if (x > xwr) {
		temp |= R;
	}
	if (y < ywb) {
		temp |= B;
	}
	else if (y > ywt) {
		temp |= T;
	}
	return temp;
}
void CSLineP(int temp, float xwl, float xwr, float ywb, float ywt, float &x1, float &y1, float x2, float y2, float& x, float& y) {
	float k = (y2 - y1) / (x2 - x1);
	if ((temp & L) == 1) {
		y1 = y1 + k * (xwl - x1);
		x1 = xwl;
	}
	if ((temp & R) == 2) {
		y1 = y1 + k * (xwr - x1);
		x1 = xwr;
	}
	if ((temp & B) == 4 && y1 < ywb) {
		x1 = x1 + (ywb - y1) / k;
		y1 = ywb;
	}
	if ((temp & T) == 8 && y1 > ywt) {
		x1 = x1 + (ywt - y1) / k;
		y1 = ywt;
	}
	x = x1, y = y1;
}

void CSLine(float xwl, float xwr, float ywb, float ywt, float x1, float y1, float x2, float y2) {
	int code1 = CSLine(xwl, xwr, ywb, ywt, x1, y1);
	int code2 = CSLine(xwl, xwr, ywb, ywt, x2, y2);

	int flag = 0;
	if (code1 & code2) {
		flag = 0;
	}
	else if (code1 == 0 && code2 == 0) {
		flag = 1;
	}
	else {
		flag = 2;
	}

	if (flag == 1) {
		glBegin(GL_LINES);
		glVertex2f(x1, y1);
		glVertex2f(x2, y2);
		glEnd();
	}
	else if (flag == 2) {
		float newX1 = 0, newY1 = 0;
		float newX2 = 0, newY2 = 0;
		CSLineP(code1, xwl, xwr, ywb, ywt, x1, y1, x2, y2, newX1, newY1);
		//交換兩點的座標
		float tempx = x1, tempy = y1;
		x1 = x2;
		x2 = tempx;
		y1 = y2;
		y2 = tempy;
		CSLineP(code2, xwl, xwr, ywb, ywt, x1, y1, x2, y2, newX2, newY2);

		if (!(newX1 >= xwr && newX2 >= xwr) && !(newX1 <= xwl && newX2 <= xwl) && !(newY1 <= ywb && newY2 <= ywb) && !(newY1 >= ywt && newY2 >= ywt)) {
			glBegin(GL_LINES);
			glVertex2f(newX1, newY1);
			glVertex2f(newX2, newY2);
			glEnd();
		}
	}
}

void Init() {
	glClear(GL_COLOR_BUFFER_BIT);
	glLineWidth(5);

	if (c1 == 0) {
		glColor3f(0.f, 0.8f, 0.8f);
		glBegin(GL_LINES);
		glVertex2f(20, 120);
		glVertex2f(430, 440);
		glEnd();
	}

	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	glColor3f(0.f, 0.8f, 0.5f);
	if (c1 > 0) {
		glRectf(rec.xx0, rec.yy0, rec.xx1, rec.yy1);
		c3 = 1;
	}
	if (c3 == 1) {
		glColor3f(1.0f, 0.0f, 0.0f);
		CSLine(rec.xx0, rec.xx1, rec.yy1, rec.yy0, 20, 120, 430, 440);
	}

	if (f) {
		glRectf(rec.xx0, rec.yy0, temX, tempY);
	}

	glutSwapBuffers();
}

void ChangeSize(GLsizei w, GLsizei h) {
	if (h == 0) {
		h = 1;
	}
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0f, 600.f, 0.f, 600.f, 1.f, -1.f);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}
void mouseF(int button, int state, int x, int y) {
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
		if (!f) {
			f = true;
			rec.xx0 = x;
			rec.yy0 = 600 - y;
			c0 = 1;
		}
		else {
			f = false;
			c1 = 1;
			rec.xx1 = x;
			rec.yy1 = 600 - y;
			glutPostRedisplay();
		}
	}
	if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
		f = false;
		rec.xx0 = 0;
		rec.yy0 = 0;
		rec.xx1 = 0;
		rec.yy1 = 0;
		c1 = 0;
		c0 = 0;
		c3 = 0;
		glutPostRedisplay();
	}
}
void mouseMoveF(int x, int y) {
	if (f) {
		temX = x;
		tempY = 600 - y;
		glutPostRedisplay();
	}
}

void main(int argc, char **argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(600, 600);
	glutCreateWindow("CSLine");

	glutDisplayFunc(Init);

	glutReshapeFunc(ChangeSize);
	glutMouseFunc(mouseF);
	glutPassiveMotionFunc(mouseMoveF);

	glClearColor(0.f, 0.5f, 0.5f, 1.f);
	glutMainLoop();
}
執行結果:
liang-barsky裁剪:
#include<glut.h>
#include<iostream>
using namespace std;
int LBLineClipTest(float p, float q, float &umax, float &umin) {
	float r = 0.0;
	if (p < 0.0) {
		r = q / p;
		if (r > umin) {
			return 0;
		}
		else if (r > umax) {
			umax = r;
		}
	}
	else if (p > 0.0) {
		r = q / p;
		if (r < umax) {
			return 0;
		}
		else if (r < umin) {
			umin = r;
		}
	}
	else if (q < 0.0) {
		return 0;
	}
	return 1;
}
void LBLineClip(float xwl, float xwr, float ywb, float ywt, float x1, float y1, float x2, float y2) {
	float umax, umin, deltax, deltay, xx2, yy2, xx1, yy1;
	deltax = x2 - x1;
	deltay = y2 - y1;
	umax = 0.0;
	umin = 1.0;
	if (LBLineClipTest(-deltax, x1 - xwl, umax, umin)) {
		if (LBLineClipTest(deltax, xwr - x1, umax, umin)) {
			if (LBLineClipTest(-deltay, y1 - ywb, umax, umin)) {
				if (LBLineClipTest(deltay, ywt - y1, umax, umin)) {
					xx1 = int(x1 + umax*deltax + 0.5);
					yy1 = int(y1 + umax*deltay + 0.5);
					xx2 = int(x1 + umin*deltax + 0.5);
					yy2 = int(y1 + umin*deltay + 0.5);
				}
				glBegin(GL_LINES);
				glVertex2f(xx1, yy1);
				glVertex2f(xx2, yy2);
				glEnd();
			}
		}
	}
}
void RenderSence() {
	glClear(GL_COLOR_BUFFER_BIT);
	glPolygonMode(GL_FRONT_AND_BACK , GL_LINE);
	glLineWidth(5);
	glColor3f(1.0f, 0.0f, 0.0f);
	glRectf(20, 20, 120, 130);
	LBLineClip(20, 120, 20, 130, 30, 190, 80, 10);
	glFlush();
}
void ChangeSize(GLsizei w, GLsizei h) {
	if (h == 0) {
		h = 1;
	}
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	if (w <= h) {
		glOrtho(-100.0f, 250.0f, -100.0f, 250.0f * h / w, 1.0f, -1.0f);
	}
	else {
		glOrtho(-100.0f, 250.0f * w / h, -100.0f, 250.0f, 1.0f, -1.0f);
	}
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}
void SetupRC() {
	glClearColor(0.0f, 0.5f, 0.5f, 1.0f);
}
void main(int argc, char **argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(600, 600);
	glutCreateWindow("GLLine");
	glutDisplayFunc(RenderSence);
	glutReshapeFunc(ChangeSize);
	SetupRC();
	glutMainLoop();
}





相關推薦

opengl實現csliang-barsky直線裁剪演算法

#include<glut.h> #include<iostream> #define L 00001 #define R 00002 #define B 00004 #define T 00010 #define M 00000 #define

Liang-Barsky直線裁剪演算法

引數化演算法(Cyrus-Beck) 考慮凸多邊形區域R和直線段P1P2:P(t)=(P2-P1)*t+P1 設A是區域R的邊界上一點,N是區域邊界在A點的內法線向量 則對於線段P1P2上任一點P(t) N ·(P(t)-A)< 0 →

Android圓形頭像設定(實現相機相簿選擇並裁剪)相容6.0/7.0

Android圓形頭像設定(實現相機、相簿選擇並裁剪)相容Android 7.0/6.0 Android7.0新增了許可權修改、目錄被限制訪問、多視窗 等等,最近在做頭像設定的時候,執行到Android7.0的機子上,拍照和進相簿都報錯:FileUriExpo

Cohen-Sutherland直線裁剪演算法

在二維觀察中,需要在觀察座標系下根據視窗大小對二維圖形進行裁剪(clipping),只將位於視窗內的圖形變換到視區輸出。直線段裁剪是二維圖形裁剪的基礎,裁剪的實質是判斷直線段是否與視窗相交,如相交則進一步確定直線段上位於視窗內的部分。 編碼原理 Cohen-Sutherland直

實驗3 直線裁剪演算法

1.實驗目的: 理解直線裁剪的基本原理; 驗證直線的編碼裁剪演算法,參考網路資料實現樑友棟-Barsky裁剪演算法; 瞭解與掌握OpenGL滑鼠操作。 2.實驗內容: 本次實驗主要結合滑鼠畫執行緒序來驗證編碼裁剪演算法和實現樑友棟-Barsky裁剪演算法,具

計算機圖形學常用演算法實現9 樑友棟-Barskey裁剪演算法

這個演算法的效率比前面提到的Cohen-Sutherland要高 思路是把直線表示為引數方程形式, x= x1+udx y = y1+udy 由xmin<x<xmax ymin<y<ymax 可以得到四個不等式,簡化成同一個形式up<q 當p不等於0的時候,可以

OPENGL—引數裁剪Liang-Barsky演算法

#include"stdafx.h" #include<Gl/glut.h> #include <cmath> #include <iostream> using namespace std; void drawpolygon(doub

三維空間兩條直線的最短距離最近點及C++演算法實現

未經許可請勿轉載 在雙目視覺立體空間重建中,會根據兩個相機中的物體影象座標,求取給定三維座標系的三維座標,而可以根據物體 影象座標、相機內參、給定座標系的相機外參,求取相機光軸線的方程,從而實現立體重建,內外參、直線方程請執行 搜尋學習,本文主要是解決在已知空間兩直線求最短

直線生成演算法實現:分別利用DDA演算法中點Bresenham演算法和改進的Bresenham演算法掃描轉換直線段P1P2

直線生成演算法的實現:分別利用DDA演算法、中點Bresenham演算法和改進的Bresenham演算法掃描轉換直線段P1P2,其中P1為(0, 0), P2為(8, 6)。   // fhk.cpp : 定義控制檯應用程式的入口點。 // #include <iost

Mac下OpenGL實現直線演算法-OpenGL教程(2)

前言 這個學期有選了計算機圖形學這門課程。第一週上課老師的作業便是用OpenGL實現直線,那我就寫一篇詳細教程吧! // // main.cpp // opengl_helloword

使用__iter__ , 和__reversed__ 實現反向叠代器

兩個 ever init 需要 clas highlight nbsp utf 實現 內置的iter(), reversed()函數可以進行正反向叠代,如果需要定制正反向叠代,要怎麽做呢? 事實上iter函數是調用的__iter__方法, reversed,則是調用的__r

以最少的代碼讓自定的model實現NSCodingNSCopying協議

key bject 根據 方法 conf imp oid 自定義 code 項目中用到了自定義的model:Person(栗子)。此model需要可以實現歸檔的功能,但是屬性非常多,且類似的model很多。如果按照常規去寫歸檔的代碼,那麽無論是寫起來還是維護起來都非常困難。

js實現撥號短信及保存至通訊錄

light href div pre asc logs javascrip code 通訊 1.js實現一鍵撥號功能 <a href="tel://139xxxxxxxx">139xxxxxxxx</a> 2.js實現一鍵發送短信功能 <

OpenGL實現粒子的隨機運動

ids i++ isp 實現 include switch ota matrix demo 一、目的: 掌握OpenGL中粒子的繪制、隨機數的使用 二、代碼: #include "stdafx.h" #include <GL/glut.h> #includ

OpenGL實現跳躍的立體小球

運動 目的 class for sha 上下左右 span pen eof 一、目的 掌握OpenGL中顯示列表對象的使用方法。 二、示例代碼 #include "stdafx.h" #include <GL/glut.h> #include <cm

實現QQ微信新浪微博和百度第三方登錄(Android Studio)

wiki protocol super cli 路徑 參考 syn jar包 all 前言: 對於大多數的APP都有第三方登錄這個功能,自己也做過幾次,最近又有一個新項目用到了第三方登錄,所以特意總結了一下關於第三方登錄的實現,並拿出來與大家一同分享; 各大開放平臺註冊

用原生js實現ajaxjsonp

原生js 斜杠 lang settime 發送數據 tro upper 類型 之前 一、原生js實現ajax $.ajax({ url: ‘‘, type: ‘post‘, data: {name: ‘zhaobao‘, age: 20}, dataTy

十一接口(接口的概念,實現,繼承,實現抽象類與抽象方法(抽象類,抽象方法概念,使用)

輸出 重寫 關鍵字 new clas main ride ring strac 接口 接口是一種用來定義程序的協議,它描述可屬於任何類和結構的一組相關行為。 接口可由方法、屬性、事件和索引器這四種成員類型的任何組合構成,但不能包含字段。 接口通過類繼承來實現,一個類雖然只能

Spring用form表單實現PUTDELETE提交

reason inpu data 瀏覽器 請求方式 很多 work 部分 不支持 在REST服務中必不可少的需要PUT、DELETE提交,但是目前很多的遊覽器並不支持。所以在使用REST前需要進行一些額外的處理。 具體解決方案如下: 1,先添加一個filter。這個fi

泛微OA系統助力澳美鋁業實現訂單采購一體化管理

oa系統、協同oa、移動辦公廣東澳美鋁業有限公司成立於2005年,是由馬來西亞上市公司Press Metal Berhad 投資興建的大型鋁業擠壓企業,在歐洲、中東、澳大利亞、南美州及吉隆坡均設有生產和銷售基地。旗下擁有廣東澳美高新科技有限公司、澳美廣屏精密科技實業有限公司兩家子公司。一、案例背景作為一家從事