【OpenGL】中點法畫橢圓
仍然可以看成是Bresenham演算法的一個應用,書上叫它“中點法”(原因是當我們不能確定取哪個座標的時候,就用兩個待定的座標的中點代入方程來幫助判斷)。
Bresenham演算法歸根到底要解決的就是“下一個點怎麼選更精確”這個問題,解決的套路是:
1)先給出一個判別函式,這個函式就是所要畫的曲線的方程式;
2)求解這個判別函式的遞推式;
2)總是從畫素點更密集的方向開始選點(方便起見從x開始,每次加1);
3)判斷下一個點x+1對應的理論座標和實際座標的差距,選差距小的作為y座標;
4)不斷重複3),直到達到臨界條件(通常是斜率,一般只需要考慮斜率小於1的情形,其他對稱解決)
橢圓的思路是一樣的,只是方程更復雜,所以推導過程更繁瑣一點:
注意這裡是用斜率來確定臨界點,隱函式求導可以得到k=-2x^2Ry/2y^2Rx。每次的分子分母也可以用增量的方式來計算。
最終的程式碼:
執行效果://中心點法畫橢圓 #include<iostream> using namespace std; #include<windows.h> #include<gl/glut.h> /*函式申明*/ void myDisplay(void);//用來呼叫eclipseBres() int round(const float x); void setPixel(int x,int y);//畫點的函式 void symmetricPoints(int xc,int yc,int rx,int ry);//在對稱位置畫點 void changeSize(GLsizei w, GLsizei h);//視窗大小改變時呼叫的登記函式 void eclipseBres(int xc,int yc,int rx,int ry);//畫橢圓的主要函式 /*函式實現*/ void myDisplay(void){ eclipseBres(120,120,50,100); } int round(const float x){ return (x+0.5); } void setPixel(int x,int y){ //使用OpenGL的glVertex2i來畫點 glPointSize(2.0f); glBegin(GL_POINTS); glVertex2i(x,y); glEnd(); glFlush(); } void symmetricPoints(int xc,int yc,int rx,int ry){ setPixel(xc+rx,yc+ry); setPixel(xc-rx,yc+ry); setPixel(xc+rx,yc-ry); setPixel(xc-rx,yc-ry); } void changeSize(GLsizei w, GLsizei h){ //這個函式和OpenGL顯示有關,和演算法本身無關 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); } void eclipseBres(int xc,int yc,int rx,int ry){ int x=0,y=ry; int rx2=rx*rx,ry2=ry*ry; int tworx2=2*rx2,twory2=2*ry2; int px=0,py=tworx2*y; int p=round(ry2-rx2*ry+0.25*rx2); symmetricPoints(xc,yc,x,y); while(py>px){ x++; px+=twory2; if(p<0) p+=ry2+px; else{ y--; py-=tworx2; p+=ry2+px-py; } symmetricPoints(xc,yc,x,y); } //region2 p=round(ry2*(x+0.5)*(x+0.5)+rx2*(y-1)*(y-1)-rx2*ry2); while(y>0){ y--; py-=tworx2; if(p>0) p+=rx2-py; else{ x++; px+=twory2; p+=rx2-py+px; } symmetricPoints(xc,yc,x,y); } } int main(int argc,char* argv[]){ //OPenGL顯示圖形的框架 glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE); glutInitWindowPosition(200,200); glutInitWindowSize(400,400); glutCreateWindow("練習"); glutDisplayFunc(&myDisplay); glutReshapeFunc(changeSize); glutMainLoop(); return 0; }
相關推薦
【OpenGL】中點法畫橢圓
仍然可以看成是Bresenham演算法的一個應用,書上叫它“中點法”(原因是當我們不能確定取哪個座標的時候,就用兩個待定的座標的中點代入方程來幫助判斷)。 Bresenham演算法歸根到底要解決的就是“下一個點怎麼選更精確”這個問題,解決的套路是: 1)先給出一個判別函式,
【OpenGL】中點圓、橢圓生成演算法
中點圓生成演算法 因為圓具有對稱性,一次性可以畫8個點 中點圓生成演算法-C++程式碼 #include<GL\glut.h> #include<iostream> #include<cmath> using
【OpenGL】使用DDA演算法畫線
DDA(數字微分分析儀...好高大上的樣子)演算法其實就是利用直線方程來生成直線的演算法,給定起點(x0,y0)和終點(xEnd,yEnd),這條直線就唯一確定了,它的斜率是k=(yEnd-y0)/(xEnd-x0)。對於x方向我們取增量為1,那麼下一個x值,即xi+1=x
【OpenGL】Shader實例分析(七)- 雪花飄落效果
mouse llb cto 接下來 pix lan details effect art 轉發請保持地址:http://blog.csdn.net/stalendp/article/details/40624603 研究了一個雪花飄落效果。感覺挺不錯的。分享給大家,效
【轉】【OPenGL】opengl 64位 配置
技術 添加 os x 源代碼 lar ebs 庫文件 定義 software 1.GLEW The OpenGL Extension Wrangler Library (GLEW) is a cross-platform open-source C/C++ extensio
【OpenGL】Shader實例分析(九)- AngryBots中的主角受傷特效
spa 2.7 imp ttext pro tint shader 作用 負責 轉發請保持地址:http://blog.csdn.net/stalendp/article/details/40859441 AngryBots是Unity官方的一個非常棒的樣例。非常有研究
【技巧】算法競賽中對拍程序的寫法
定向 軟件 err 出錯 OS 進行 小數據 goto 隨機數 在競賽過程中一個對拍程序可以幫你排除許多錯誤, 如果擔心自己寫的正解被一些小數據卡掉, 我們通常會寫個對拍程序來檢查正解的正確性, 通過大量數據觀察正解與暴力的輸出是否相同。 我們首先拿出我們寫的可能會超時但是
【OpenGL】LNK1104 無法打開文件“freeglutd.lib”
lease 編譯 idt pen spa bubuko 預處理器 無法打開 解決 新建的OpenGL程序編譯時經常會出現[LNK1104 無法打開文件“freeglutd.lib”]問題,如果freeglutd.lib確實放到了正確的路徑下,通常可以通過添加“NDEBUG”
【OpenGL】平移變換矩陣
AC pan sel .com light alt style 分享圖片 平移 摘自:http://ogldev.atspace.co.uk/www/tutorial06/tutorial06.html 以下等式計算平移:等式左邊,左項為旋轉平移矩陣M,右項為原坐標P,
【leetcode】 算法題3 無重復字符的最長子串
sim bcb IT wid VM str longest solid eat 問題 給定一個字符串,找出不含有重復字符的最長子串的長度。 示例: 給定 "abcabcbb" ,沒有重復字符的最長子串是 "abc" ,那麽長度
【轉】算法的時間復雜度
語句 期望 cmp sum 去掉 函數 要求 rcm 實例 定義:如果一個問題的規模是n,解這一問題的某一算法所需要的時間為T(n),它是n的某一函數 T(n)稱為這一算法的“時間復雜性”。當輸入量n逐漸加大時,時間復雜性的極限情形稱為算法的“漸近時間復雜性”。我們常用大O
【原始碼】牛頓法求解實值函式的根
示例:[ x, ex ] = newton( ‘exp(x)+x’, ‘exp(x)+1’, 0, 0.5*10^-5, 10 ) f:輸入函式 df:輸入函式的導數 x0:函式根的初值估計 tol:誤差容忍度 namx:求解最大迭代次數 x:求解輸出的近似根 e
【OpenGL】-010 使用shader
【OpenGL】-010 使用shader 文章目錄 【OpenGL】-010 使用shader 1. OpenGL中的shader 2. 示例 2. shader的使用流程 1. OpenGL中的shade
【OpenGL】-009 GLUT中處理鍵盤滑鼠事件
【OpenGL】-009 GLUT中處理鍵盤滑鼠事件 鍵盤和滑鼠是GUI程式獲取使用者輸入的重要方式,在windows程式中,通過WM_KEY_DOWN/WM_KEY_UP/WM_LBUTTONDOWN/WM_RBUTTONDOWN等訊息的響應,使用者可以方便的處理鍵盤滑鼠的輸入。在
【OpenGL】-008 GLUT中的定時器
【OpenGL】-008 GLUT中的定時器 定時器是視窗程式中的一個重要功能,用於按照固定的時間間隔之後執行某些特定動作。在window程式中,有WM_TIMER訊息進行響應。在使用GLUT進行視窗管理的程式中,如何進行定時器操作? 文章目錄 【OpenG
【OpenGL】-007 在視窗上顯示一個三角形
【OpenGL】-007 在視窗上顯示一個三角形 文章目錄 【OpenGL】-007 在視窗上顯示一個三角形 1. 在視窗上顯示一個三角形 2. 效果 3. 備註 1. 在視窗上顯示一個三角形 /* Fi
最簡單的 UBO(Uniform Buffer Object) 【OpenGL】【GLSL】
一、引入 Uniform Buffer Object / Uniform Block 的 原因 1) 如果程式涉及了多個 Shader 程式,而且它們使用同一個Uniform變數,那麼你就需要為每個 Shader 程式單獨管理它們。當一個程式被連結時,OpenGL 會自動生成
【P1865】篩法求素數+區間!
#include<bits/stdc++.h> using namespace std; const int maxn=1000010; bool a[maxn]; int primesum[maxn]; void printPrimes(){ memset(a,true,size
【LeetCode】回溯法 backtracking(共39題)
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica } 【10】Regular Expression Matching 【17】Letter Combinations of a Phone Number 【
【JAVA】二分法查詢指定元素的下標
如果,我們要在一個數組中查詢某個指定的元素,可以使用二分法,從而大大降低查詢效率,前提是所給定的陣列是已經排序的; 下面是一個小小的例子 public class BinarySearch{ publ