1. 程式人生 > >計算機圖形學(二)中點畫圓演算法講解與原始碼

計算機圖形學(二)中點畫圓演算法講解與原始碼

近些天寫了一些關於計算機圖形學的演算法和原始碼!

如果喜歡轉載請標明出處:並非菜鳥的部落格http://blog.csdn.net/syx1065001748

關於中點畫圓,大家都知道是根據圓的8分對稱性質,然後畫出1/8圓之後再進行對稱畫點,就可以得到完整的圓了。首先給出圓的一般演算法,是使用中點畫圓的統法,在原點畫圓!然後進行平移來得到!

下邊是使用橡皮筋的方法實現的畫圓方法!

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);
 }
以上是畫圓演算法的一般情況其中CX和CY分別是經過圓心(0,0),平移過後的圓心也就是偏移量!然後給一段關於如何將畫圓顯示在自己設定的畫素座標系中

以上是效果圖

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;
}

希望能幫到大家!