平時, 用慣了API、CDC和封裝好的內建函式,關於畫線,畫圓這些東西都是信手拈來…
最近學習電腦圖形學,不得不深入內部研究一下底層演算法…
在這裡貼幾個代碼分享一下!
(這裡只給出MFC的OnDraw函數)
一、畫線的三個演算法:
1。DDA(數值微分)法:
void CDDALineView::OnDraw(CDC* pDC)
{
CDDALineDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
int x,x0(200),y0(200),x1(500),y1(500);
float dx,dy,y,k;
dx=x1-x0;
dy=y1-y0;
k=dy/dx;
y=y0;
for(x=x0;x<=x1;x++)
{
pDC->SetPixel(x,(int)(y+0.5),RGB(255,0,0));
y+=k;
}
}
2.中點畫線演算法
void CMidpointLineView::OnDraw(CDC* pDC)
{
CMidpointLineDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
int a,b,d1,d2,d,x,y;
int x0(200),x1(500),y0(200),y1(500);
a=y0-y1;
b=x1-x0;
d=2*a+b;
d1=2*a;
d2=2*(a+b);
x=x0;
y=y0;
pDC->SetPixel(x,y,RGB(0,255,0));
while(x<x1)
{
if(d<0)
{
x++;
y++;
d+=d2;
}
else
{
x++;
d+=d1;
}
pDC->SetPixel(x,y,RGB(0,255,0));
}
}
3。Bresenham演算法:
void CBresenhamline2View::OnDraw(CDC* pDC)
{
CBresenhamline2Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
int x0(200),y0(200),x1(500),y1(500);
int x,y,dx,dy;
dx=x1-x0;
dy=y1-y0;
int e=-dx;
x=x0;
y=y0;
for(int i=0;i<=dx;i++)
{
pDC->SetPixel(x,y,RGB(0,0,255));
x=x+1;
e=e+2*dy;
if(e>=0)
{
y++;
e=e-2*dx;
}
}
}
二、中點畫圓演算法:
void CMidPointCircleView::OnDraw(CDC* pDC)
{
CMidPointCircleDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
int r=100; //半徑
int m(300),n(250); //圓心座標
int x,y;
float d;
x=0;
y=0+r;
d=1.25-r;
//中點畫圓演算法
pDC->SetPixel(m+x,n+y,RGB(255,0,0));
pDC->SetPixel(m+y,n+x,RGB(255,0,0));
pDC->SetPixel(m-x,n+y,RGB(255,0,0));
pDC->SetPixel(m+y,n-x,RGB(255,0,0));
pDC->SetPixel(m+x,n-y,RGB(255,0,0));
pDC->SetPixel(m-y,n+x,RGB(255,0,0));
pDC->SetPixel(m-x,n-y,RGB(255,0,0));
pDC->SetPixel(m-y,n-x,RGB(255,0,0));
while(x<=y)
{
if(d<0)
d+=2*x+3;
else
{
d+=2*(x-y)+5;
y--;
}
x++;
pDC->SetPixel(m+x,n+y,RGB(255,0,0));
pDC->SetPixel(m+y,n+x,RGB(255,0,0));
pDC->SetPixel(m-x,n+y,RGB(255,0,0));
pDC->SetPixel(m+y,n-x,RGB(255,0,0));
pDC->SetPixel(m+x,n-y,RGB(255,0,0));
pDC->SetPixel(m-y,n+x,RGB(255,0,0));
pDC->SetPixel(m-x,n-y,RGB(255,0,0));
pDC->SetPixel(m-y,n-x,RGB(255,0,0));
}
}