您好,登錄后才能下訂單哦!
這篇文章主要講解了OpenGL繪制貝塞爾曲線的方法,內容清晰明了,對此有興趣的小伙伴可以學習一下,相信大家閱讀完之后會有幫助。
最終效果圖:
通過3個點形成一條貝塞爾曲線
1. 鼠標問題
在使用鼠標獲取坐標的時候,要知道鼠標獲取的坐標和屏幕坐標是不同的;
openGL使用右手坐標
從左到右,x遞增
從下到上,y遞增
從遠到近,z遞增
而鼠標是從左到右增x,同時從上到下也是增y
所以在求 y 的時候,用(屏幕大小-y)來獲取
2. 繪制
setpoint 用來繪制點
setline 用來繪制線
setBezier 用來繪制貝塞爾曲線
其中公式的意義可以參考百科:
實際繪制的時候就是不斷的增加t,求出下一點的值然后將兩個鏈接起來,然后再將下一個點作為起點,再求出下下一個點
Api解釋在代碼中
#include "GL\glut.h" #include <math.h> #include <Windows.h> //這是一個點的類,用于存儲其中點的坐標 class Point { public: int x, y; void setxy(int _x, int _y) { x = _x; y = _y; } }; //點的數量 static int POINTSNUM = 0; //用于存儲點的集合,因為繪制的都是4個點的貝塞爾曲線,所以數組大小為4 static Point points[4]; //初始化函數 void init(void) { glClearColor(1.0, 1.0, 1.0, 0); //設定背景為黑色 glColor3f(0.0,0.0,0.0); //繪圖顏色為白色 glPointSize(2.0); //設定點的大小為2*2像素的 glMatrixMode(GL_PROJECTION); // 設定合適的矩陣 glLoadIdentity(); // 是一個無參的無值函數,其功能是用一個4×4的單位矩陣來替換當前矩陣,實際上就是對當前矩陣進行初始化。也就是說,無論以前進行了多少次矩陣變換,在該命令執行后,當前矩陣均恢復成一個單位矩陣,即相當于沒有進行任何矩陣變換狀態 gluOrtho2D(0.0,600.0,0.0,480.0); //平行投影,四個參數分別是x,y范圍 } //繪制點 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函數 void display() { glClear(GL_COLOR_BUFFER_BIT); glFlush(); } // 鼠標事件 void mymouseFunction(int button, int state, int x, int y) { if (state == GLUT_DOWN) // 如果鼠標按下,不區分左右鍵的 { points[POINTSNUM].setxy(x,480- y); // 這里求鼠標點的坐標的時候 // 設置點的顏色,繪制點 glColor3f(1.0,0.0,0.0); setPoint(points[POINTSNUM]); // 設置線的顏色,繪制線 glColor3f(1.0,0.0,0.0); if(POINTSNUM > 0) setline(points[POINTSNUM-1],points[POINTSNUM]); //如果達到了4個繪制貝塞爾曲線,并在之后給計數器清零 if (POINTSNUM == 3) { //繪制貝塞爾曲線 glColor3f(0.0, 0.0, 1.0); // 設定貝塞爾曲線的顏色 Point p_current = points[0]; //設為起點 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("第四次作業"); init(); // 初始化 glutMouseFunc(mymouseFunction); // 添加鼠標事件 glutDisplayFunc(display); // 執行顯示 glutMainLoop(); //進人GLUT事件處理循環 return 0; }
看完上述內容,是不是對OpenGL繪制貝塞爾曲線的方法有進一步的了解,如果還想學習更多內容,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。