1. 程式人生 > >計算機圖形學(一)DDA畫線演算法講解與原始碼

計算機圖形學(一)DDA畫線演算法講解與原始碼

很早之前就想寫一個計算機圖形學系列的講解,可是隻寫了2篇,然後就擱置了很長一段時間,現在也算是有時間來繼續之前的想法了。

首先介紹一下演算法

已知直線過端點P0(x0,y0),P1(x1,y1)的直線段的斜率K=(y1-y0)/(x1-x0),畫線的過程為:從x的左端點x0開始,向x的右端點步進,步長=1(畫素),按y=kx+b來計算y座標,並取畫素點(x,round(y))作為當前座標點。但這樣計算 每一個點需要做一個乘法,一個加法。設步長為∆x,有xi+1=xi+1;於是yi+1=k(xi+1)+b=kxi+1,這樣的話就能簡化演算法,只用加法進行計算。


本文程式畫線使用的是橡皮筋,然後可以自定義畫素大小,更方便容易看出計算出來的點。而且更能瞭解這個演算法的過程。

其中主要的演算法:

void CDrawlineView::DDAline(int x0, int y0, int x1, int y1)   //DDA演算法!
{
	int x;
	float dx,dy,y,k;
	dx=float(x1-x0);
	dy=float(y1-y0);
	k=dy/dx;
	y=float(y0);
	x=float(x0);
	Adjustment(x,x0,x1,y0,y1,y,k);
}
按照自己設定的畫素,進行相應的調整:
void CDrawlineView::Adjustment(int &x,int &x0,int &x1,int y0,int y1,float &y,float &k)  //判斷後的畫線演算法DDA的精華
{
	CClientDC dc(this);
	dc.SetROP2(R2_NOTXORPEN);
	CBrush bru;
	bru.CreateSolidBrush(RGB(255,255,0));
	CBrush *oldbru=dc.SelectObject(&bru);
	if(Judge(k)==1||Judge(k)==3)    //斜率為0~1或-1~0的時候
	{
		if(x0>x1)      //向左上方畫線
		{
			for(x=Ajust(x0,gaps);x>=x1;x-=gaps)
			{
				dc.Ellipse(x-int(gaps/2.0),Ajust(y,gaps)+int(gaps/2.0),x+int(gaps/2.0),Ajust(y,gaps)-int(gaps/2.0));
				y=y-k*gaps;
			}
		}
		else           //向右下方畫線
		{
			for(x=Ajust(x0,gaps);x<=x1;x+=gaps)
			{
				dc.Ellipse(x-int(gaps/2.0),Ajust(y,gaps)+int(gaps/2.0),x+int(gaps/2.0),Ajust(y,gaps)-int(gaps/2.0));
				y=y+k*gaps;
			}
		}
	}
	if(Judge(k)==2||Judge(k)==4) //斜率大於1或小於-1的時候
	{
		k=1.0/k;
		if(y0<y1)      //向左上方畫線
		{
			for(y=Ajust(y0,gaps);y<=y1;y+=gaps)
			{
				dc.Ellipse(Ajust(x,gaps)-int(gaps/2.0),y+int(gaps/2.0),Ajust(x,gaps)+int(gaps/2.0),y-int(gaps/2.0));
				x=x+k*gaps;
			}
		}
		else           //向右下方畫線
		{
			for(y=Ajust(y0,gaps);y>=y1;y-=gaps)
			{
				dc.Ellipse(Ajust(x,gaps)-int(gaps/2.0),y+int(gaps/2.0),Ajust(x,gaps)+int(gaps/2.0),y-int(gaps/2.0));
				x=x-k*gaps;
			}
		}
	}
	dc.SelectObject(&oldbru);
}
int CDrawlineView::Judge(float k)    //判斷斜率K的大小
{
	if(k>=0&&k<=1)
		return 1;
	if(k>1)
		return 2;
	if(k<0&&k>=-1)
		return 3;
	if(k<-1)
		return 4;
	return 4;
}

int CDrawlineView::Ajust(int x,int gaps)  //調整x,y到自己的方格點上!
{
	if(x%gaps>gaps/2)
		x=int(x/gaps+1)*gaps;
	else
		x=int(x/gaps)*gaps;
	return x;
}


其中主要關注直線的斜率的4種情況。然後4中不同的情況也可分為2種來畫。

說的也不夠詳細,大概就是這樣子,如若本文中有什麼不對的地方,還請大家指出。謝謝。

相關推薦

計算機圖形DDA演算法講解原始碼

很早之前就想寫一個計算機圖形學系列的講解,可是隻寫了2篇,然後就擱置了很長一段時間,現在也算是有時間來繼續之前的想法了。 首先介紹一下演算法: 已知直線過端點P0(x0,y0),P1(x1,y1)的直線段的斜率K=(y1-y0)/(x1-x0),畫線的過程為:從x的

計算機圖形掃描線多邊形填充演算法講解原始碼

如果喜歡轉載請標明出處: 並非菜鳥菜鳥的部落格 在這裡先說下演算法的實現過程 本人覺得這個演算法實現起來還是有點難度的!很多人都不願意去看太多描述性的文字,所以對這個演算法的過程是什麼大概也不知道,那麼我在這裡簡要的說一些! 演算法實現過程中應用兩個資料結構:

計算機圖形中點畫圓演算法講解原始碼

近些天寫了一些關於計算機圖形學的演算法和原始碼! 如果喜歡轉載請標明出處:並非菜鳥的部落格http://blog.csdn.net/syx1065001748 關於中點畫圓,大家都知道是根據圓的8分

計算機圖形 視頻顯示設備_1_CRT原理

http color size 安裝 ref p s 這一 計算機圖形學 指定 第 1 章 圖形系統概述 如今。計算機圖形學的作用與應用已經得到了廣泛承認。大量的圖形硬件和軟件系統已經應用 到了差點兒全部的領域。通用計算機甚至很多手持計算器也已經

學習shader之前必須知道的東西之計算機圖形渲染...

shader到底是幹什麼用的?shader的工作原理是什麼?         其實當我們對這個問題還很懵懂的時候,就已經開始急不可耐的要四處搜尋有關shader的資料,恨不得立刻上手寫一個出來。但看了一些資料甚至看了不少cg的語法之後,我們還是很迷茫,UNITY_MATRIX_MVP到底是個什麼矩陣?它和v

計算機圖形

概念: 研究通過計算機將資料轉換為圖形並在專門顯示裝置上顯示的原理方法和技術的學科 高質量的計算機圖形離不開高效能的計算機圖形硬體裝置。一個圖形系統通常是由圖形處理器,圖形輸入裝置和輸出裝置構成。 圖形顯示裝置* 圖形的輸出包括圖形的顯示和繪製。圖形的顯

計算機圖形輸出圖元_3_算法_2_DDA算法

通過 程序 之間 tro 取整 xen git 方程 class DDA算法? ? ? ? 數字微分分析儀(digital differential analyzer, DDA)方法是一種線段掃描轉換算法。基於使用等式(3

計算機圖形_幾何變換_1_基本的二維幾何變換()

4 .幾何變換        使用線段和填充區等圖元來描述場景,並利用屬性來輔助這些圖元。我們給出了掃描線演算法,可以將圖元顯示在光柵裝置上。現在,再看看可用於物件重定位或改變大小的變換操作。這些操作也用於將世界座標系中的場景描述轉換為輸出裝置上顯示的觀察子程式中。另外,它

計算機圖形輸出圖元_13_素陣列圖元

畫素陣列圖元        除了線段、多邊形、圓和其他圖元之外,圖形軟體包常提供一些子程式用於顯示由矩形的彩色陣列定義的各種形狀。矩形的網格圖案一可通過數字化(掃描)一張照片或其他圖形來獲得,也可以使用圖形程式來生成。陣列中每一顏色值對映到一個或多個螢幕畫素位置。如第2章所

計算機圖形學習記錄Breseham演算法

Breseham演算法 首先為了方便直接看演算法程式碼的朋友直接看核心程式碼和結果,在這裡直接貼出演算法程式碼。 void DDADrawLine::BreasehamDrawLine(int x0, int y0, int x1, int y1) {

MFC計算機圖形2

mct tid spc DdGzS cin html uem ubd dcs sdsdzi狗聘毫渤口毫http://huiyi.docin.com/hnbkw203d1e5gw濫良瘟侍探蝗http://weibo.com/p/10050563731520645atr4g回救

計算機圖形幾何變換_5_三維空間的幾何變換_1_三維平移

三維平移 在三維齊次座標表示中,任意點P = (x, y, z)通過將平移距離tx, ty,和tz加到P的座標上而平移到位置P’= (x', y', z'): 我們可以用下面等式中的矩陣形式來表達三維平移操作。 但現在座標位置P和P’用4元列向量的齊次座標表示,且變換操

計算機圖形_圖元的屬性_16_ 反走樣_6_直線亮度差的校正

直線亮度差的校正        為了減輕階梯狀效應,對直線進行反走樣也為如圖4.52所示的另一種光柵效果提供了校正。使用相同數目畫素所繪製的兩條線,對角線還是比水平線長√2倍。例如,當水平線的長度為10 cm時,對角線的長度超過14cm。這導致的視覺效果是對角線顯得比水平線

計算機圖形幾何變換_4_二維複合變換_5_其他二維變換_2_錯切

二維複合變換_5_其他二維變換_2_錯切          錯切(shear)是一種使物件形狀發生變化的變換,經過錯切的物件好像是由已經相互滑動的內部夾層組成。兩種常用的錯切變換是移動x座標值的錯切和移動Y座標值的錯切。相對於x軸的x方向錯切由下列變換矩陣1產生: 該矩陣將

計算機圖形——微表面模型

計算機圖形學中基於物理建模的渲染技術之所以能給人極佳的視覺體驗,是因為利用這些渲染技術能夠很真實的反映出每種物體獨有的“質感”。我們能通過人眼觀察來感受物體表面“質感”的原因,也是因為物體表面反射周圍環境的特性不同而造成的,因此對物體表面的物理建模對於其表面本身的質感表現至關重要。對物體表面的建模,最簡單的是

計算機圖形幾何變換_2_矩陣表示_2_二維矩陣

二維平移矩陣使用齊次座標方法,座標位置的二維平移可表示為下面的矩陣乘法。 該平移操作可簡寫為: 其中T(tx,ty)等式中3*3矩陣。在平移引數沒有混淆的情況下,可以使用T表示平移矩陣。二維旋轉矩陣類似地,繞座標系原點的二維旋轉變換方程可以表示為矩陣形式: 或      

計算機圖形幾何變換_4_二維複合變換

二維複合變換        利用矩陣表示式,可以通過計算單個變換的矩陣乘積,將任意的變換序列組成複合變換矩陣(compsite transformation matrix)。形成變換矩陣的乘積經常稱為矩陣的合併(concatenation)或複合(compsistion)。

計算機圖形_圖元的屬性_16_ 反走樣_7_區域邊界的反走樣

區域邊界的反走樣   直線的反走樣概念也可以用於區域的邊界,從而消除其鋸齒形的外貌。我們可以將這種程式加加入到掃描線演算法中,在生成區域時來平滑區域輪廓。假如系統具有允許畫素重定位的功能,那麼就可以將邊界畫素位置調整到更靠近區域邊界來實現對區域邊界的平滑處理。

計算機圖形輸出圖元_10_多邊形填充區_3_內-外測試

內-外測試        各種圖形處理經常需要鑑別物件的內部區域。識別簡單物件如凸多邊形、圓或橢圓的內部通常是一件很容易的事情。但有時我們必須處理較複雜的物件。例如,我們可能描述一個圖3.46所示的有相交邊的複雜填充區。在該形狀中,xy平面上哪一部分為物件邊界的“內部”、哪

MFC計算機圖形3

之前我們已經可以畫出直線和曲線了。但是演算法雖容易理解,但是複雜度高,今天就介紹比較流行的DDA畫線法,還有,對滑鼠進行事件有所響應,即,在畫板上,滑鼠左鍵單擊,移動至另外一個地方鬆開,此時在這兩個點之間畫一條線。 DDA畫線 演算法程式碼 void