Bresenham畫線算圖形學中最基礎的知識了,可惜我並沒有選修過圖形學,所有還是有必要熟悉一下。
上一篇用到的畫線函數應該算是數值微分法,也是我最常用的一種方法,不過這種方法似乎並不是很好。
這里的畫線方法比上一種方法好。
算法原理如下:
過各行各列象素中心構造一組虛擬網格線。按直線從起點到終點的順序計算直線與各垂直網格線的交點,然后確定該列象素中與此交點最近的象素。
該算法的巧妙之處在於采用增量計算,使得對於每一列,只要檢查一個誤差項的符號,就可以確定該列的所求象素。
更細節的原理參考這里。
隨機畫出的一些線:
matlab代碼如下:
main.m
clear all;close all;clc; h=256; w=256; img=zeros(h,w); for i=1:100 x1=round(rand()*(w-1))+1; y1=round(rand()*(h-1))+1; x2=round(rand()*(w-1))+1; y2=round(rand()*(h-1))+1; img=BresenhamDraw(img,x1,y1,x2,y2); figure(1); imshow(img,[]) end
BresenhamDraw.m
function img=BresenhamDraw(img,x1,y1,x2,y2) if x1~=x2 k=(y2-y1)/(x2-x1); flag=0; %斜率判斷標記位 if abs(k)>1 %如果斜率大於1,則把x和y方向置換 flag=1; k=1/k; [y1 x1]=Swap(x1,y1); [y2 x2]=Swap(x2,y2); end %計算開始畫線的像素 mi=min(x1,x2); ma=max(x1,x2); if mi==x1 s=y1; else s=y2; end d=0; for i=mi:ma if flag==0 img(s,i)=1; else img(i,s)=1; end d=d+k; %自變量i每加1,根據d是否超過一個像素來確定因變量s增加或減少 if d>=1 d=d-1; s=s+1; elseif d<=-1 d=d+1; s=s-1; end end end end
Swap.m
function [y x]=Swap(x1,y1) x=y1; y=x1; end