這是第一篇部落格,順便深入學習一下markdown語法。
之後的圖形學文章都使用c++實現。
數值微分法
中點畫線法
bresenham畫線演算法
數值微分法通過計算直線的斜率,計算每個x對應的y座標,並取畫素x,round(y)。本方法直觀可行,但執行效率低。由於每步都需要進行浮點乘法運算與捨入運算,故需要增量的方法。
首先計算直線的斜率: k=
δy/δ
x k=δ
y/δx
接著推導增量方式計算y座標: yi
+1=k
xi+1
+b=k
(xi+
δx)+
b=kx
i+kδ
x+b=
yi+k
δx(1) (1)yi
+1=k
xi+1
+b=k
(xi+
δx)+
b=kx
i+kδ
x+b=
yi+k
δx由於δx
=1δ x=
1,所以每次y y
遞增k'>kk。
利用opencv+cpp進行實現。考慮了|k
|∈[0
,1]與
|k|∉
[0,1
] |k|
∈[0,
1]與|
k|∉[
0,1]
兩種情形
這裡注意opencv中at(i0,i1)函式是操作第i0行第i1列,所以需要把xy反過來。
總體還是比較簡單。cv配置、函式搞的比較麻煩。opencv還需多多熟練。
首先假定k∈
[0,1
] k∈[
0,1]
之間。 根據(
x0,y
0)(x
1,y1
) (x0
,y0)
(x1,
y1)兩點座標可以得到直線方程: f(
x,y)
=ax+
by+c
f (x
,y)=
ax+b
y+c其中,a=
y0−y
1,b=
x1−x
0,c=
x0y1
−x1y
0 a=y0
−y1,
b=x1
−x0,
c=x0
y1−x
1y0當f
(x,y
)>0 f(x
,y)>
0時,點在直線上方。當確定p點位置後,下乙個畫素點處的中點m的判別式為:f(
m)=f
(x+1
,y+0.5)=
f(x,
y)+a
+0.5
b f(m
)=f(
x+1,
y+0.5)=f
(x,y
)+a+
0.5b
此時判斷符號。若m點在直線上方,則選m下方的畫素點。那麼下乙個需要判斷的中點的判別式為: f(
xp+2
,yp+
0.5)=f
(m)+
a f(x
p+2,
yp+0.5)=
f(m)
+a如果m點在直線下方,則選上方的畫素點,下乙個中點的判別式為 f(
xp+2
,yp+
1.5)=f
(m)+
a+b f(x
p+2,
yp+1.5)=
f(m)
+a+b
而f(m)的初始值: f(
m0)=
f(x0
,y0)
+a+0.5b=
a+0.5b
f (m
0)=f
(x0,
y0)+
a+0.5b=a
+0.5
b
void midpointline(mat& m, const
int x0, const
int y0, const
int x1, const
int y1, const cv::vec3b& v)
else
m.at(y, x) = v;}}
由於把d的判別全部乘2了,可以避免小數的運算。斜率在其他範圍內只要換換前後兩點的順序、換換x,y,就可以解決。
還是首先假定k∈
[0,1
] k∈[
0,1]
。 假設x列的畫素已確定,那麼下乙個畫素列座標為x+1,行下標為y或y+1,具體是哪個取決於誤差項d大於0.5還是小於0.5。每次x增加1,則誤差隨之增加k。程式中設e=d-0.5,則可判斷e的正負值。當
d>
1 d
>
1時,則只需執行d=
d−1 d=d−1。
void bresenhamline(mat& m, const
int x0, const
int y0, const
int x1, const
int y1, const vec3b& v)}}
以上。 直線段掃瞄轉換演算法
數值微分 dda 法 設過端點p0 x0,y 0 p1 x1,y1 的直線段為l p0,p 1 則直線段 l的斜率dda畫線演算法程式 void ddaline int x0,int y0,int x1,int y1,int color 注意 我們這裡用整型變數color表示象素的顏色和灰度。舉例 ...
多邊形掃瞄轉換演算法
1.多邊形的頂點表示轉換為多邊形的點陣表示 1 頂點表示 用多邊形的頂點的序列來描述多邊形,幾何意義強 佔記憶體少。2 點陣表示 用位於多邊形內的畫素的集合來描述多邊形。3 轉換基本思想 按掃瞄線順序,計算掃瞄線與多邊形的相交區間,再用要求的顏色顯示這些區間的所有象素 2.x掃瞄線演算法的演算法步驟...
直線掃瞄演算法
每次想寫點東西的時候,都不知道該寫點什麼,想起來在ai for game developer上看到使用bresenham演算法來做tile地形中的追逐和逃避演算法,正好可以寫點關於直線畫法的東西,這也是計算機圖形學中的基本圖元生成演算法了,還是比較簡單的。很多人都寫過,網上資料也很多,這裡也就不怕再...