日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【计算机图形学 】绘制椭圆 | OpenGL+鼠标交互

發布時間:2023/12/16 编程问答 112 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【计算机图形学 】绘制椭圆 | OpenGL+鼠标交互 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 其他計算機圖形學實驗
  • 前言
  • 1.輔助畫橢圓算法
  • 2.橢圓的中點算法(兩種)
  • 3.改變鼠標動作響應函數
  • 4. 完整代碼
  • 5. 總結

其他計算機圖形學實驗

傳送門

前言

實現繪制橢圓的中點算法,并和鼠標進行交互。

具體原理略過,會貼上完整代碼,可直接運行。

環境:
vs2019,OpenGL的庫(可以搜索如何用vs使用OpenGL的庫,可以使用vs自帶的插件或者其他方法,很方便)

要點:
1.設計畫橢圓的算法。設置橢圓中心和長短半軸的全局變量,通過鼠標得到全局變量的值,再傳入函數,進行橢圓的繪制。
2.改變鼠標點擊和鼠標拖拽的響應事件。

最終效果:
用鼠標在界面上拖拽,就會生成一個橢圓

1.輔助畫橢圓算法

由于橢圓的對稱性,我們只用畫出其四分之一即可。

//輔助畫橢圓算法 void OvalPoints(int x, int y, int x0, int y0) {glVertex2i(x + x0, y + y0);glVertex2i(-x + x0, y + y0);glVertex2i(x + x0, -y + y0);glVertex2i(-x + x0, -y + y0); }

2.橢圓的中點算法(兩種)

方法一

/*橢圓的中點算法*/ void MidpointOval(int x0, int y0, int a, int b) {glClear(GL_COLOR_BUFFER_BIT);//清除窗口顯示內容glBegin(GL_POINTS);int x = 0, y = b;int a2 = a * a, b2 = b * b;float d1 = b2 + a2 * (0.25 - b);float d2 = b2 * (x + 0.5) * (x + 0.5) + a2 * (y - 1) * (y - 1) - a2 * b2;OvalPoints(x, y, x0, y0);int flag = 0; //分成上下部分的標志while (y>=0) {glBegin(GL_POINTS);OvalPoints(x, y, x0, y0);if (flag == 0) {if (a2*y<b2*x) flag = 1;}if (flag == 0) { //上半部分x++;if (d1 < 0) {d1 += b2 * (2 * x + 3);}else {y--;d1 += b2 * (2 * x + 3) + a2 * (2 - 2 * y);}}else { //下半部分y--;if (d2 >= 0) { //取正下方的點d2 += a2 * (3 - 2 * y);}else {x++;d2 += b2 * (2 * x + 2) + a2 * (3 - 2 * y);}}}glEnd();glFlush(); }

方法二

/*橢圓的中點算法*/ void MidpointOval(int x0, int y0, int a, int b) {glClear(GL_COLOR_BUFFER_BIT);//清除窗口顯示內容glBegin(GL_POINTS);int x = 0, y = b;int a2 = a * a, b2 = b * b;float d1 = b2 + a2 * (0.25 - b);float d2 = b2 * (x + 0.5) * (x + 0.5) + a2 * (y - 1) * (y - 1) - a2 * b2;//float d2 = sqrt(b * (x + 0.5) + a * (y - 1)) - a * b;//glVertex2i(x0, y0);OvalPoints(x, y, x0, y0);while (a2*y>b2*x) { //注意這個判斷!!!glBegin(GL_POINTS);OvalPoints(x, y, x0, y0);x++;//++x;if (d1 < 0) {d1 += b2 * (2 * x + 3);}else {y--;//--y;d1 += b2 * (2 * x + 3) + a2 * (2 - 2 * y);}}x--; y++;while (y > 0) {y--;if (d2 >= 0) { //取正下方的點d2 += a2 * (3 - 2 * y);}else {x++;d2 += b2 * (2 * x + 2) + a2 * (3 - 2 * y);}glBegin(GL_POINTS);OvalPoints(x, y, x0, y0);}glEnd();glFlush(); }

3.改變鼠標動作響應函數

//鼠標拖動 void dragmouse(int x, int y) {m1 = x;n1 = y;mm = (m0 + m1) / 2;nn = (n0 + n1) / 2;a = abs(m1 - m0) / 2;b = abs(n1 - n0) / 2;DrawOval(); //畫線glFlush(); }//鼠標監聽,畫點 void mymouse(int button, int state, int x, int y) {if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {m1 = x;n1 = y;mm = (m0 + m1) / 2;nn = (n0 + n1) / 2;a = abs(m1 - m0) / 2;b = abs(n1 - n0) / 2;printf("橢圓起始點坐標為:(%d,%d),長半軸為:%d,短半軸為:%d\n", m0, n0, a, b);DrawOval(); glFlush();}if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { //按下鼠標,是起點m0 = x;n0 = y;} }

4. 完整代碼

#include<cstdio> #include<cstdlib> #include<cmath> #include<gl\glut.h> using namespace std;int m0, n0, m1, n1;//聲明全局變量 int mm, nn; //橢圓的中心點 int a, b; //橢圓的長半軸和短半軸 int winwidth = 800, winheight = 500;//窗口長寬 void DrawOval(); //實際上畫圓的函數 void MidpointOval(int, int, int, int); //橢圓的中點算法//實際上畫圓的函數 void DrawOval() {MidpointOval(mm, nn, a, b); //橢圓的中點算法 }//輔助畫橢圓算法 void OvalPoints(int x, int y, int x0, int y0) {glVertex2i(x + x0, y + y0);glVertex2i(-x + x0, y + y0);glVertex2i(x + x0, -y + y0);glVertex2i(-x + x0, -y + y0); }/*橢圓的中點算法*/ void MidpointOval(int x0, int y0, int a, int b) {glClear(GL_COLOR_BUFFER_BIT);//清除窗口顯示內容glBegin(GL_POINTS);int x = 0, y = b;int a2 = a * a, b2 = b * b;float d1 = b2 + a2 * (0.25 - b);float d2 = b2 * (x + 0.5) * (x + 0.5) + a2 * (y - 1) * (y - 1) - a2 * b2;OvalPoints(x, y, x0, y0);/*方法一*/while (a2*y>b2*x) { //注意!!!glBegin(GL_POINTS);OvalPoints(x, y, x0, y0);x++;//++x;if (d1 < 0) {d1 += b2 * (2 * x + 3);}else {y--;//--y;d1 += b2 * (2 * x + 3) + a2 * (2 - 2 * y);}}x--; y++;while (y > 0) {y--;if (d2 >= 0) { //取正下方的點d2 += a2 * (3 - 2 * y);}else {x++;d2 += b2 * (2 * x + 2) + a2 * (3 - 2 * y);}glBegin(GL_POINTS);OvalPoints(x, y, x0, y0);}/*方法二*///int flag = 0; //分成上下部分的標志//while (y>=0) {// glBegin(GL_POINTS);// OvalPoints(x, y, x0, y0);// if (flag == 0) {// if (a2*y<b2*x) flag = 1;// }// if (flag == 0) { //上半部分// x++;// if (d1 < 0) {// d1 += b2 * (2 * x + 3);// }// else {// y--;// d1 += b2 * (2 * x + 3) + a2 * (2 - 2 * y);// }// }// else { //下半部分// y--;// if (d2 >= 0) { //取正下方的點// d2 += a2 * (3 - 2 * y);// }// else {// x++;// d2 += b2 * (2 * x + 2) + a2 * (3 - 2 * y);// }// }//}glEnd();glFlush(); }//鼠標拖動 void dragmouse(int x, int y) {m1 = x;n1 = y;mm = (m0 + m1) / 2;nn = (n0 + n1) / 2;a = abs(m1 - m0) / 2;b = abs(n1 - n0) / 2;DrawOval(); //畫線glFlush(); }//鼠標監聽,畫點 void mymouse(int button, int state, int x, int y) {if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {m1 = x;n1 = y;mm = (m0 + m1) / 2;nn = (n0 + n1) / 2;a = abs(m1 - m0) / 2;b = abs(n1 - n0) / 2;printf("橢圓起始點坐標為:(%d,%d),長半軸為:%d,短半軸為:%d\n", m0, n0, a, b);DrawOval(); glFlush();}if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { //按下鼠標,是起點m0 = x;n0 = y;} }void init() {glClearColor(1, 1, 1, 1);//設置繪制窗口顏色為白色glClear(GL_COLOR_BUFFER_BIT);//清除窗口內容glPointSize(3.0f);//設置點的大小/*設置為投影類型模式和其他觀察參數*/glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0, winwidth, winheight, 0);glColor3f(0, 1, 1);//設置畫點的顏色 }int main(int argc, char** argv) {glutInit(&argc, argv);//初始化glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//設置繪制模式glutInitWindowPosition(350, 200);//設置窗口出現的位置glutInitWindowSize(winwidth, winheight);//設置窗口大小glutCreateWindow("畫橢圓");//創建窗口init();glutDisplayFunc(DrawOval);//繪制回調函數,glut機制,它覺得需要重新繪制的時候就會執行glutMouseFunc(mymouse);//鼠標監聽回調函數glutMotionFunc(dragmouse);//鼠標拖動glutMainLoop(); }

5. 總結

橢圓是在圓的基礎上進行改變,算法更難了一點。要注意橢圓從上半部分變到下半部分的判斷點。因為這個判斷點弄錯了,找了好久的bug都沒找出來

總結

以上是生活随笔為你收集整理的【计算机图形学 】绘制椭圆 | OpenGL+鼠标交互的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。