OpenGL繪制貝塞爾曲線
本文實(shí)例為大家分享了OpenGL繪制貝塞爾曲線的具體代碼,供大家參考,具體內(nèi)容如下
最終效果圖:
通過(guò)3個(gè)點(diǎn)形成一條貝塞爾曲線
1. 鼠標(biāo)問(wèn)題
在使用鼠標(biāo)獲取坐標(biāo)的時(shí)候,要知道鼠標(biāo)獲取的坐標(biāo)和屏幕坐標(biāo)是不同的;
openGL使用右手坐標(biāo)
從左到右,x遞增
從下到上,y遞增
從遠(yuǎn)到近,z遞增
而鼠標(biāo)是從左到右增x,同時(shí)從上到下也是增y
所以在求 y 的時(shí)候,用(屏幕大小-y)來(lái)獲取
2. 繪制
setpoint 用來(lái)繪制點(diǎn)
setline 用來(lái)繪制線
setBezier 用來(lái)繪制貝塞爾曲線
其中公式的意義可以參考百科:
實(shí)際繪制的時(shí)候就是不斷的增加t,求出下一點(diǎn)的值然后將兩個(gè)鏈接起來(lái),然后再將下一個(gè)點(diǎn)作為起點(diǎn),再求出下下一個(gè)點(diǎn)
Api解釋在代碼中
#include "GL\glut.h" #include <math.h> #include <Windows.h> //這是一個(gè)點(diǎn)的類(lèi),用于存儲(chǔ)其中點(diǎn)的坐標(biāo) class Point { public: int x, y; void setxy(int _x, int _y) { x = _x; y = _y; } }; //點(diǎn)的數(shù)量 static int POINTSNUM = 0; //用于存儲(chǔ)點(diǎn)的集合,因?yàn)槔L制的都是4個(gè)點(diǎn)的貝塞爾曲線,所以數(shù)組大小為4 static Point points[4]; //初始化函數(shù) void init(void) { glClearColor(1.0, 1.0, 1.0, 0); //設(shè)定背景為黑色 glColor3f(0.0,0.0,0.0); //繪圖顏色為白色 glPointSize(2.0); //設(shè)定點(diǎn)的大小為2*2像素的 glMatrixMode(GL_PROJECTION); // 設(shè)定合適的矩陣 glLoadIdentity(); // 是一個(gè)無(wú)參的無(wú)值函數(shù),其功能是用一個(gè)4×4的單位矩陣來(lái)替換當(dāng)前矩陣,實(shí)際上就是對(duì)當(dāng)前矩陣進(jìn)行初始化。也就是說(shuō),無(wú)論以前進(jìn)行了多少次矩陣變換,在該命令執(zhí)行后,當(dāng)前矩陣均恢復(fù)成一個(gè)單位矩陣,即相當(dāng)于沒(méi)有進(jìn)行任何矩陣變換狀態(tài) gluOrtho2D(0.0,600.0,0.0,480.0); //平行投影,四個(gè)參數(shù)分別是x,y范圍 } //繪制點(diǎn) void setPoint(Point p) { glBegin(GL_POINTS); glVertex2f(p.x, p.y); glEnd(); glFlush(); } // 繪制直線 void setline(Point p1, Point p2) { glBegin(GL_LINES); glVertex2f(p1.x,p1.y); glVertex2f(p2.x, p2.y); glEnd(); glFlush(); } // 繪制貝塞爾曲線 Point setBezier(Point p1, Point p2, Point p3, Point p4,double t) { Point p; double a1 = pow((1 - t), 3); double a2 = pow((1 - t), 2) * 3 * t; double a3 = 3 * t*t*(1 - t); double a4 = t*t*t; p.x = a1*p1.x + a2*p2.x + a3*p3.x + a4*p4.x; p.y = a1*p1.y + a2*p2.y + a3*p3.y + a4*p4.y; return p; } //display函數(shù) void display() { glClear(GL_COLOR_BUFFER_BIT); glFlush(); } // 鼠標(biāo)事件 void mymouseFunction(int button, int state, int x, int y) { if (state == GLUT_DOWN) // 如果鼠標(biāo)按下,不區(qū)分左右鍵的 { points[POINTSNUM].setxy(x,480- y); // 這里求鼠標(biāo)點(diǎn)的坐標(biāo)的時(shí)候 // 設(shè)置點(diǎn)的顏色,繪制點(diǎn) glColor3f(1.0,0.0,0.0); setPoint(points[POINTSNUM]); // 設(shè)置線的顏色,繪制線 glColor3f(1.0,0.0,0.0); if(POINTSNUM > 0) setline(points[POINTSNUM-1],points[POINTSNUM]); //如果達(dá)到了4個(gè)繪制貝塞爾曲線,并在之后給計(jì)數(shù)器清零 if (POINTSNUM == 3) { //繪制貝塞爾曲線 glColor3f(0.0, 0.0, 1.0); // 設(shè)定貝塞爾曲線的顏色 Point p_current = points[0]; //設(shè)為起點(diǎn) for (double t = 0.0; t <= 1.0; t += 0.05) { Point P = setBezier(points[0], points[1], points[2], points[3], t); setline(p_current, P); p_current = P; } POINTSNUM = 0; } else { POINTSNUM++; } } } int main(int argc, char *argv[]) { glutInit(&argc, argv); //固定格式 glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); //緩存模式 glutInitWindowSize(600, 480); //顯示框的大小 glutInitWindowPosition(100, 100); //確定顯示框左上角的位置 glutCreateWindow("第四次作業(yè)"); init(); // 初始化 glutMouseFunc(mymouseFunction); // 添加鼠標(biāo)事件 glutDisplayFunc(display); // 執(zhí)行顯示 glutMainLoop(); //進(jìn)人GLUT事件處理循環(huán) return 0; }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++ boost 時(shí)間與日期處理詳細(xì)介紹
這篇文章主要介紹了C++ boost 時(shí)間與日期處理詳細(xì)介紹的相關(guān)資料,這里提供實(shí)例代碼,及實(shí)現(xiàn)效果,需要的朋友可以參考下2016-11-11C語(yǔ)言函數(shù)的遞歸和調(diào)用實(shí)例分析
一個(gè)函數(shù)在它的函數(shù)體內(nèi)調(diào)用它自身稱(chēng)為遞歸調(diào)用。這種函數(shù)稱(chēng)為遞歸函數(shù)。C語(yǔ)言允許函數(shù)的遞歸調(diào)用。在遞歸調(diào)用中,主調(diào)函數(shù)又是被調(diào)函數(shù)。執(zhí)行遞歸函數(shù)將反復(fù)調(diào)用其自身,每調(diào)用一次就進(jìn)入新的一層2013-07-07C++輸出斐波那契數(shù)列的兩種實(shí)現(xiàn)方法
以下是對(duì)C++中輸出斐波那契數(shù)列的兩種實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-10-10C++利用數(shù)組(一維/二維)處理批量數(shù)據(jù)的方法
對(duì)于簡(jiǎn)單的問(wèn)題,使用簡(jiǎn)單的數(shù)據(jù)類(lèi)型就可以了,但是對(duì)于有些需要處理的數(shù)據(jù),只用以上簡(jiǎn)單的數(shù)據(jù)類(lèi)型是不夠的,難以反映出數(shù)據(jù)的特點(diǎn),也難以有效的進(jìn)行處理,本文小編給大家介紹了C++利用數(shù)組(一維/二維)處理批量數(shù)據(jù)的方法,需要的朋友可以參考下2023-10-10C++實(shí)現(xiàn)圖書(shū)管理系統(tǒng)(文件操作與類(lèi))
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)圖書(shū)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03