計算機圖形學(二)中點畫圓演算法講解與原始碼
阿新 • • 發佈:2019-02-18
近些天寫了一些關於計算機圖形學的演算法和原始碼!
如果喜歡轉載請標明出處:並非菜鳥的部落格http://blog.csdn.net/syx1065001748
關於中點畫圓,大家都知道是根據圓的8分對稱性質,然後畫出1/8圓之後再進行對稱畫點,就可以得到完整的圓了。首先給出圓的一般演算法,是使用中點畫圓的統法,在原點畫圓!然後進行平移來得到!
下邊是使用橡皮筋的方法實現的畫圓方法!
以上是畫圓演算法的一般情況其中CX和CY分別是經過圓心(0,0),平移過後的圓心也就是偏移量!然後給一段關於如何將畫圓顯示在自己設定的畫素座標系中void MidPointCircle(int x0,int y0,int x1,int y1) //(x0,y0)滑鼠左鍵落下的點和(x1,y1)MouseMove的點 { CClientDC dc(this); int oldmode=dc.SetROP2(R2_NOTXORPEN); int r=(max(x1,x0)-min(x1,x0))/2;//求的圓心 int x,y,cx,cy; cx=(x1+x0)/2;//圓心X座標 cy=(y0+y1)/2;//圓心Y座標 float d; //判別D x=0; y=r; d=1.25-r;//避免取反無法顯示</span> dc.Ellipse(x+cx-int(gaps/2.0),y+cy+int(gaps/2.0),x+cx+int(gaps/2.0),y+cy-int(gaps/2.0)); dc.Ellipse(y+cx-int(gaps/2.0),x+cy+int(gaps/2.0),y+cx+int(gaps/2.0),x+cy-int(gaps/2.0)); dc.Ellipse(x+cx-int(gaps/2.0),-y+cy+int(gaps/2.0),x+cx+int(gaps/2.0),-y+cy-int(gaps/2.0)); dc.Ellipse(-y+cx-int(gaps/2.0),x+cy+int(gaps/2.0),-y+cx+int(gaps/2.0),x+cy-int(gaps/2.0)); while(x<y) { if(d<0) d=d+2*x+3; else { d=d+2*(x-y)+5; y--; } x++; CirclePoint(cx,cy,x,y); } dc.SetROP2(oldmode); } void CirclePoint(int cx,int cy,int x, int y)//輔助畫點 { CClientDC dc(this); int oldmode=dc.SetROP2(R2_NOTXORPEN); if(y==x) { dc.SetPixel(x+cx,y+cy,RGB(255,255,0)); dc.SetPixel(x+cx,-y+cy,RGB(255,255,0); dc.SetPixel(-x+cx,-y+cy,RGB(255,255,0)); dc.SetPixel(-x+cx,y+cy,RGB(255,255,0)); } else if(x!=y+gaps) { dc.SetPixel(x+cx,y+cy,RGB(255,255,0)); dc.SetPixel(-x+cx,y+cy,RGB(255,255,0)); dc.SetPixel(x+cx,-y+cy,RGB(255,255,0)); dc.SetPixel(y+cx,x+cy,RGB(255,255,0)); dc.SetPixel(-y+cx,x+cy,RGB(255,255,0)); dc.SetPixel(-y+cx,-x+cy,RGB(255,255,0)); dc.SetPixel(-x+cx,-y+cy,RGB(255,255,0)); dc.SetPixel(y+cx,-x+cy,RGB(255,255,0)); } dc.SetROP2(oldmode); }
以上是效果圖
MidPointCircle(int x0,int y0,int x1,int y1) //(x0,y0)和(x1,y1)兩個點數遍落下兩個點 { CClientDC dc(this); int oldmode=dc.SetROP2(R2_NOTXORPEN); int r=Ajust((maxn(x1,x0)-mine(x1,x0))/2,gaps); int x,y,cx,cy; cx=Ajust((x1+x0)/2,gaps); cy=Ajust((y0+y1)/2,gaps); float d; x=0; y=r; d=1.25-r; dc.Ellipse(x+cx-int(gaps/2.0),y+cy+int(gaps/2.0),x+cx+int(gaps/2.0),y+cy-int(gaps/2.0)); dc.Ellipse(y+cx-int(gaps/2.0),x+cy+int(gaps/2.0),y+cx+int(gaps/2.0),x+cy-int(gaps/2.0)); dc.Ellipse(x+cx-int(gaps/2.0),-y+cy+int(gaps/2.0),x+cx+int(gaps/2.0),-y+cy-int(gaps/2.0)); dc.Ellipse(-y+cx-int(gaps/2.0),x+cy+int(gaps/2.0),-y+cx+int(gaps/2.0),x+cy-int(gaps/2.0)); while(x<y) { if(d<0) d=d+2*x+3; else { d=d+2*(x-y)+5; y-=gaps; } x+=gaps; CirclePoint(cx,cy,x,y); } dc.SetROP2(oldmode); }
CirclePoint(int cx,int cy,int x, int y) { CClientDC dc(this); int oldmode=dc.SetROP2(R2_NOTXORPEN); if(y==x) { dc.Ellipse(x+cx-int(gaps/2.0),y+cy+int(gaps/2.0),x+cx+int(gaps/2.0),y+cy-int(gaps/2.0)); dc.Ellipse(x+cx-int(gaps/2.0),-y+cy+int(gaps/2.0),x+cx+int(gaps/2.0),-y+cy-int(gaps/2.0)); dc.Ellipse(-x+cx-int(gaps/2.0),-y+cy+int(gaps/2.0),-x+cx+int(gaps/2.0),-y+cy-int(gaps/2.0)); dc.Ellipse(-x+cx-int(gaps/2.0),y+cy+int(gaps/2.0),-x+cx+int(gaps/2.0),y+cy-int(gaps/2.0)); } else if(x!=y+gaps) { dc.Ellipse(x+cx-int(gaps/2.0),y+cy+int(gaps/2.0),x+cx+int(gaps/2.0),y+cy-int(gaps/2.0)); dc.Ellipse(-x+cx-int(gaps/2.0),y+cy+int(gaps/2.0),-x+cx+int(gaps/2.0),y+cy-int(gaps/2.0)); dc.Ellipse(x+cx-int(gaps/2.0),-y+cy+int(gaps/2.0),x+cx+int(gaps/2.0),-y+cy-int(gaps/2.0)); dc.Ellipse(y+cx-int(gaps/2.0),x+cy+int(gaps/2.0),y+cx+int(gaps/2.0),x+cy-int(gaps/2.0)); dc.Ellipse(-y+cx-int(gaps/2.0),x+cy+int(gaps/2.0),-y+cx+int(gaps/2.0),x+cy-int(gaps/2.0)); dc.Ellipse(-y+cx-int(gaps/2.0),-x+cy+int(gaps/2.0),-y+cx+int(gaps/2.0),-x+cy-int(gaps/2.0)); dc.Ellipse(-x+cx-int(gaps/2.0),-y+cy+int(gaps/2.0),-x+cx+int(gaps/2.0),-y+cy-int(gaps/2.0)); dc.Ellipse(y+cx-int(gaps/2.0),-x+cy+int(gaps/2.0),y+cx+int(gaps/2.0),-x+cy-int(gaps/2.0)); } //*/ dc.SetROP2(oldmode); }
Ajust(int x,int gaps) //調整x,y到自己的方格點上! gaps是方格大小!
{
if(x%gaps>gaps/2)
x=int(x/gaps+1)*gaps;
else
x=int(x/gaps)*gaps;
return x;
}
希望能幫到大家!