中點畫線法

來源:互聯網
上載者:User

 中點畫線法 收藏
演算法目的:畫一條直線

演算法思想:

判斷兩個像素點的重點是在直線的下方,上方還是直線上,從而確定該選擇那一個像素點。

線內:F(x,y) ==0;

上方:F(x,y) > 0;

下方:F(x,y) < 0;

------------------------------------------------------------------------------------------------------------------------------------

證明:若是像素點在直線上,則肯定滿足直線方程,則將像素點(x0,y0)帶入方程得:

ax0 + by0 + c = 0;

由於直線下方的點在和直線上的點的x座標相同時,其縱座標小於直線上的點:

故ax0 + by + c  < 0;(y < y0);

同理:直線上方的點(x0,y),ax0 + by + c > 0; (y > y0);

-------------------------------------------------------------------------------------------------------------------------------------

尋找中點:

--------------------------------------------------------------------------------------------------------------------------------------

當|k| < 1 && k > 0時;

由於此時,橫座標的變化速度大於縱座標,故此時我們以橫座標的變化為基準.

取直線上任意一點(xp,yp).這一點已確定作為直線上的一點,那麼我們在確定一下點時,就應該尋找(xp+1,yp),(xp+1,yp+1)兩個像素點的中點(xp+1,yp+0.5);並判斷該點是處於直線的那個方向:

直線上:可以兩點任意一點。

上方: 取(xp+1,yp);

下方: 取(xp+1,yp+1);

*************************

如何判斷該點在直線的那個方向呢?

由上述表述可知:

線內:F(x,y) ==0;

上方:F(x,y) > 0;

下方:F(x,y) < 0;

故我們只需把該店帶入方程,並判斷方程的正負即可:

d0 = a(xp+1) + b(yp+0.5) + c

 --->  d0 = axp + byp + c + a + 0.5b;

若我們令: d = axp + byp + c;

則: d0 = d + a + 0.5b;

現在我們只需判斷d0的正負即可判斷點在直線的方向,從而就可以確定該選擇點(xp+1,yp),還是點(xp+1,yp+1);

若d0 < 0;--->(xp+1,yp+1);

若d0 > 0;--->(xp+1,yp);

若d0==0;--->兩者均可.

現在分別討論下每種情況:

d0 < 0; ---->(xp+1,yp+1)

我們來算一下下個中點的值:

下一個中點應該為:(xp+2,yp+1.5);

d1 = a(xp+2) + b(yp+1.5) + c;

---> d1 = axp + byp + c + 2a + 1.5b;

---> d1 = axp + byp + c + a + 0.5b + a + b;

---> d1 = d0 + a + b;

我們可以看出當d0 < 0時,下一個中點的增量為 a+b.故我們可以通過增量計算下一個中點,而不用再通過座標重新計算中點值了;

d0 > 0; ---> (xp+1,yp);

我們算下這種情況下的中點值:

下一個中點應該為:(xp+2,yp+0.5)

d2 = a(xp+2) + b(yp+0.5) + c;

---> d2 = axp + byp + c + 2a + 0.5b;

---> d2 = d + a + 0.5b + a;

---> d2 = d0 + a;

我們可以看出當d0 > 0時,下一個中點的增量為 a,故我們可以通過+a得到下一個中點值.

當d0 == 0;時,由於選擇哪種情況都可以,故我們可以把它放入上面任意一種情況之中.

我們在看一下d0值.

d0 = d + a + 0.5b;

由於 d = axp + byp + c;

且點(xp,yp)在直線上,所以d == 0;所以我們判斷d0的正負只需判斷a + 0.5b的正負即可,而我們再求下一個中點的值來判斷正負時,只需加上增量,來判斷相加之後的值的正負即可.

---------------------------------------------------------------------------------------------------------------

|k| >= 1;時同理.

---------------------------------------------------------------------------------------------------------------

演算法開始:

我們假設從(x0,y0)開始畫直線:由於(x0,y0)在直線上.

故: ax0 + by0 + c = 0;

則d0 = a + 0.5b.由於我們使用的只是d的符號,而增量都是整數,故我們可以用2d來代替d來擺脫浮點數。

故 d = 2a + b; d1 = 2(a+b); d2 = 2a;

*******************************

我們該如何計算a,b的值呢?

下面我們將畫線已知的兩點(x0,y0),(x1,y1)帶入直線方程:ax + by + c = 0;得:

a / b = y0 - y1/ x1 - x0;

現在我們將直線方程變形一下:

y = -a/b x - c/b;

由此可知,只要a/b c/b的值確定後,直線方程就確定了,a,b是何值無關緊要只要滿足a/b的值即可.

故我們可以令:

a = y0 - y1; b = x1 - x0;

 演算法思想基本上算是分析完成了。該開始寫代碼了。基本上都是思想容易,想轉換為正確的代碼就難了:為了寫出正確的代碼,我們現在理一下思路,我們應該把直線分為幾種情況呢?

應該有四種情況:

因為直線的斜率絕對值是否大於1,以及直線的斜率是否大於0 都將會影響到我們的演算法:

故我們這樣分類:

① 0 < k < = 1

② k > 1

③ -1 < k <= 0

④ k <= -1;

好的,我們想在思路應該是更清晰一步了,我們只需對各個分類進行處理就好了。

 

本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/Joe_IceWind/archive/2009/10/04/4631475.aspx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.