在lcd顯示屏上的指定點畫出直線,點,圓
本文源於
親測可行,覺得很有意義,拿過來以備以後用
//-----------畫點函式。引數:座標,顏色-------------------
void draw_point(int x, int y, int clor)
//-------------畫圓函式。引數:圓心,半徑,顏色----------
// 畫1/8圓 然後其他7/8對稱畫
// ---------------->x
// |(0,0) 0
// | 7 1
// | 6 2
// | 5 3
// (y)v 4
//// l = x^2 + y^2 - r^2
void draw_circle(int x, int y, int r, int color)
}}//-----------畫線。引數:起始座標,終點座標,顏色--------
void draw_line(int x1,int y1,int x2,int y2,int color)
x1+=1;
e+=dy;}}
else // 2/8 octant
y1+=1;
e+=dx;}}
}else // dy<0
x1+=1;
e+=dy;}}
else // 7/8 octant
y1-=1;
e+=dx;}}
}
}else //dx<0
x1-=1;
e+=dy;}}
else // 3/8 octant
y1+=1;
e+=dx;}}
}else // dy<0
x1-=1;
e+=dy;}}
else // 6/8 octant
y1-=1;
e+=dx;}}
}
}}// 區域填色函式
// 引數:開始列數,結束列數,開始行數,結束行數,顏色
void fill_fb(int start_x, int end_x, int start_y, int end_y, unsigned short val)
}}void clr_fb(void)
}}
下面先簡要介紹常用的畫圓演算法(bresenham演算法),然後再具體闡述筆者對該演算法的改進。
乙個圓,如果畫出了圓上的某一點,那麼可以利用對稱性計算餘下的七段圓弧:plot(x,y),plot(y,x),plot(y,-x),plot(x,-y),plot(-x,-y),plot(-y,-x),plot(-y,x),plot(-x,y)。
1、bresenham
畫圓演算法。bresenham演算法的主要思想是:以座標原點(0,0)為圓心的圓可以通過0度到45°的弧計算得到,即x從0增加到半徑,然後利用對稱性計算餘下的七段圓弧。當x從0增加到時,y從r遞減到。
設圓的半徑為r,則圓的方程為:
f(x,y)=(x+1)2+y2-r2=0
(1)假設當前列(x=xi列)中最接近圓弧的畫素已經取為p(xi,yi),根據第二卦限1/8圓的走向,下一列(x=xi+1列)中最接近圓弧的畫素只能在p的正右方點h(xi+1,yi)或右下方點l(xi+1,yi-1)中選擇,如圖1所示。bresenham畫圓演算法採用點t(x,y)到圓心的距離平方與半徑平方之差d(t)作為選擇標準,即
d(t)=(x+1)2+y2-r2
(2)通過比較h、l兩點各自對實圓弧上點的距離大小,即根據誤差大小來選取,具有最小誤差的點為繪製點。根據公式(2)得:
對h(xi+1,yi)點有:d(h)=(xi+1)2+yi2-r2;
對l(xi+1,yi-1)點有:d(l)=(xi+1)2+(yi-1)2-r2;
根據bresenham畫圓演算法,則選擇的標準是:
如果|d(h)|<|d(l)|,那麼下一點選取h(xi+1,yi);
如果|d(h)|>|d(l)|,那麼下一點選取l(xi+1,yi-1);
如果|d(h)|=|d(l)|,那麼下一點可以取l(xi+1,yi-1),也可以選取h(xi+1,yi),我們約定選取h(xi+1,yi)。
圖1 bresenham畫圓演算法點的選取
綜合上述情況,得:
當|d(h)|>|d(l)|時,選取l點(xi+1,yi-1)為繪製點座標;
當|d(h)|<|d(l)|時,選取h點(xi+1,yi)為繪製點座標。
然後將選取的點座標作為當前座標,重複上述過程直至xi=或者yi=為止,(xi,yi)的初始值為(0,r)。
以上便是bresenham演算法的主要思想,但是上述演算法是在乙個假設下:以座標原點(0,0)為圓心。該假設實際上只是為了方便演算法的研究。但在實際嵌入式lcd顯示裝置中,往往圓心座標不是(0,0)點,而是以左上角為(0,0)點,這樣就使得在實際運用中,需要對這個演算法做很大的改進。
另外,如果完全按照bresenham畫圓演算法,那麼就會涉及到浮點運算,這使得嵌入式程式設計十分煩瑣,因為本系統中所有資料都是整型的,因此在這方面也要作一定的改進。下面根據本系統中嵌入式硬體特點和資料結構得特點,對這個演算法進行改進。
2、改進的bresenham畫圓演算法。先假設起始點為(r,0),令pi=(xi,yi)為當前的一點,那麼我們就需要在ti=(xi,yi+1)和si=(xi-1,yi+1)中選取一點,如圖2所示。
圖2 嵌入式lcd畫圓時點的選取
設(xi-1/2+e,yi+1)為s和t之間圓上的點,e是s、t中點到圓上點的誤差,帶入圓的方程(1)得:
f(xi-1/2+e,yi+1)=(xi-1/2+e)2+(yi+1)2-r2=f(xi-1/2,yi+1)+2(xi-1/2)e+e2=0
(3)在式(3)中,令
di="f"(xi-1/2,yi+1)=-2(xi-1/2)e-e2
(4)如果e<0,那麼di>0,因此選擇s=(xi-1,yi+1),根據(3)與(4)得:
di+1=f(xi-1-1/2,yi+1+1)=di-2(xi-1)+2(yi+1)+1=di+2(yi+1-xi+1)+1
(5)如果e30,那麼di£0,因此選擇t=(xi,yi+1),根據(3)與(4)得:
di+1=f(xi-1/2,yi+1+1)=di+2yi+1+1
(6)起始點是(r,0)的時候,根據(4)得di的初始值d0就是:
d0=f(r-1/2,0+1)=(r-1/2)2+1-r2=5/4-r=1-r(由於程式設計中所用資料型別均為整型,故取1-r)。
綜合上述情況,得:
當選取s=(xi-1,yi+1)時,那麼di+1=di+2(yi+1-xi+1)+1;
當選取t=(xi,yi+1)時,那麼di+1=di+2yi+1+1;
然後將選取的點座標作為當前座標,重複上述過程直至x=y,而不是xi=或者yi=,這樣就可以不用作浮點數計算了。
本專案中的lcd畫素為640×480點陣,並且資料是八位的,當橫座標和縱座標超過255時,那麼資料就不能一次傳送成功,因此需要通過位元組操作來設定高位元組,然後再傳送低位元組。因此,每次畫圓上的點時要傳送的引數至少是六個,圓心座標是四個(因為要考慮圓心座標可能大於255,因此要對其圓心座標設定高、低位元組),另外兩個是圓上的點相對於圓心的座標,但是最後要畫乙個點,需要四個引數,即改進的畫圓演算法為六個引數輸入,四個引數輸出。
用c語言在嵌入式lcd上實現改進的bresenham畫圓演算法的部分**如下:
voidmidbresenhamcircle(int r)
x++;
delay(900000);}
令附上乙個比較有意義的帖子
以上內容 均**于海之遙的部落格
純屬自己學習之用,分享一下,僅供學習交流
ESP32彩屏GUI試玩
最近發現很多家電家居產品都增加了彩屏,確實有些get到我。先帶大家欣賞一下 色彩 圖形 互動,打造極致使用者體驗 瞬間成為提公升家居牆面的 藝術品 今天我們試玩esp32彩屏的開發板wt 32 sc01是一款基於esp32面向視覺化觸控螢幕的開發板,它不僅把esp32模組效能發揮到極致,同時讓價效比...
LCD和LCD控制器
一 lcd顯示器 1 lcd簡介 lcd liquid crystal display 即液晶顯示器,是一種採用液晶控制透光度技術來實現色彩的顯示器,tft thin film transistor,薄膜電晶體 是目前最為主流的液晶顯示型別 2 lcd的介面 cpu或顯示卡發出的影象資料是ttl訊號...
強人畫的畫 )
這是在哥本哈根的街頭拍到的,這位街頭畫家,據他講,這種做畫的方式也是一種生活,他已經作畫20多年了。呵呵,當然不素偶拍滴啦 先用粉筆打底 測量一下比例是否正確 給路人講解 立體畫草稿 開始繪畫 畫的是felix貓 細節需要精心刻畫 開始完善畫面 中國舞獅和felix貓,呼之欲出 換個角大功告成 與作...