Wu反走樣算法繪制直線段


Wu反走樣算法###

原理:在我看來,Wu反走樣算法是在Bresenham算法基礎上改進了一番,它給最靠近理想直線/曲線的兩個點以不同的亮度值,以達到模糊鋸齒的效果。因為人眼看到的是線附近亮度的平均值。

MFC 中給CXXXView類添加函數
void CMy3_4View::wuLine(CPoint p0, CPoint p1)
{
	//自定義二維坐標系
	CDC *pDC = GetDC();
	CRect rect;
	GetClientRect(&rect);
	pDC->SetMapMode(MM_ANISOTROPIC);
	pDC->SetWindowExt(rect.Width(), rect.Height());
	pDC->SetViewportExt(rect.Width(), -rect.Height());
	pDC->SetViewportOrg(rect.Width()/2, rect.Height()/2);
	rect.OffsetRect(-rect.Width()/2, -rect.Height()/2);
//-----------------------------------------------------------

	CPoint p, temp;
	int dx=p1.x-p0.x;
	int dy=p1.y-p0.y;
	double k=(dy*1.00)/(dx*1.00);//計算斜率

	if(dx==0)//垂線
	{
		if(dy<0)//起點在上方,調換
		{
			temp=p0;
			p0=p1;
			p1=temp;
		}
		for(p=p0; p.y<p1.y; p.y++)//主移動方向->y,不包括p1
		{
			pDC->SetPixelV(p.x, p.y, RGB(0,0,0));
		}
	}

	else
	{
		double e=0.00;//增量

		if(k>=0 && k<=1)
		{
			if(dx<0)//p1在左側,調換
			{
				temp=p0;
				p0=p1;
				p1=temp;
			}//p0在左下

			for(p=p0; p.x<p1.x; p.x++)//主移動方向->x,不包括p1
			{
				pDC->SetPixelV(p.x, p.y, RGB(e*255, e*255, e*255));
				pDC->SetPixelV(p.x, p.y+1, RGB((1-e)*255, (1-e)*255, (1-e)*255));//不同亮度值
				e+=k;

				if(e>=1.0)
				{
					p.y++;
					e-=1;
				}
			}
			/*p0.x+=10;
			p1.x+=10;
			pDC->MoveTo(p0);
			pDC->LineTo(p1);*/
		}
		else if(k>1)
		{
			if(dy<0)//p1在左側,調換
			{
				temp=p0;
				p0=p1;
				p1=temp;
			}//p0在下方

			for(p=p0; p.y<p1.y; p.y++)//主移動方向->y,不包括p1
			{
				pDC->SetPixelV(p.x, p.y, RGB(e*255, e*255, e*255));
				pDC->SetPixelV(p.x+1, p.y, RGB((1-e)*255, (1-e)*255, (1-e)*255));
				e+=1.00/(k*1.00);

				if(e>=1.0)
				{
					p.x++;
					e-=1;
				}
			}
		}
		
		else if(k>=-1 && k<0)
		{
			e=0.00;
			if(dx<0)//p1在左上,調換
			{
				temp=p0;
				p0=p1;
				p1=temp;
			}//p0在左上
			
			for(p=p0; p.x<p1.x; p.x++)//主移動方向->x,不包括p1
			{
				pDC->SetPixelV(p.x, p.y, RGB(-1*e*255, -1*e*255, -1*e*255));
				pDC->SetPixelV(p.x, p.y-1, RGB((1+e)*255, (1+e)*255, (1+e)*255));//這里e是負數!!!
				e+=k;

				if(e<=-1.0)
				{
					p.y--;
					e+=1.0;
				}
			}
		}

		else if(k<-1)
		{
			if(dy>0)//p1在上方,調換
			{
				temp=p0;
				p0=p1;
				p1=temp;
			}//p0在上
			for(p=p0; p.y>p1.y; p.y--)//主移動方向->y,不包括p1
			{
				pDC->SetPixelV(p.x, p.y, RGB(e*255, e*255, e*255));
				pDC->SetPixelV(p.x+1, p.y, RGB((1-e)*255, (1-e)*255, (1-e)*255));
				e+=-1.0/(k*1.0);

				if(e>=1.0)
				{
					p.x++;
					e-=1;
				}
			}
		}

	}
	pDC->DeleteDC();
}
VC++ 6.0編譯通過!如有錯誤,或編譯不通過,請留言。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM