Bresenham改進算法結合wu反走樣算法畫直線

自己打造了CLine畫直線類


1.CP2類 定義了點類

class CP2  
{
public:
	CRGB clr;
	double y;
	double x;

	CP2();
	CP2(double,double,CRGB clr=CRGB());
	virtual ~CP2();

};

2.CRGB類 定義了顏色類

class CRGB  
{
public:
	double r;
	double g;
	double b;
public:
	CRGB();
	CRGB(double,double,double);
	virtual ~CRGB();

	CRGB& operator= (const CRGB& c1)
	{
		r=c1.r;
		g=c1.g;
		b=c1.b;
		return *this;
	}
	friend CRGB operator+ (const CRGB&, const CRGB&);
	friend CRGB operator- (const CRGB&, const CRGB&);
	friend CRGB operator* (const CRGB&, const CRGB&);
	friend CRGB operator* (const CRGB&, double);
	friend CRGB operator* (double, const CRGB&);
	friend CRGB operator/ (const CRGB&, double);
	friend CRGB operator+= (CRGB&, CRGB&);
	friend CRGB operator-= (CRGB&, CRGB&);
	friend CRGB operator*= (CRGB&, CRGB&);
	friend CRGB operator/= (CRGB&, double);
	void Normalize();

};

3.定義了CLine類

class CLine  
{
public:
	CP2 P1;
	CP2 P0;
public:
	void LineTo(CDC*,double,double,CRGB,BOOL anti=FALSE);
	void LineTo(CDC*,double,double,BOOL anti=FALSE);
	void LineTo(CDC*,CP2,BOOL anti=FALSE);
	void MoveTo(CDC*,double,double,CRGB);
	void MoveTo(CDC*,double,double);
	void MoveTo(CDC*,CP2);
	CLine();
	virtual ~CLine();

};

4.CLine類的實現

// Line.cpp: implementation of the CLine class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Class.h"
#include "Line.h"
#include <math.h>
#define   Round(a) int(a+0.5) //四捨五入
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CLine::CLine()
{

}

CLine::~CLine()
{

}

void CLine::MoveTo(CDC* pDC, CP2 p0)
{
	P0=p0;
}

void CLine::MoveTo(CDC* pDC, double x, double y)
{
	MoveTo(pDC,CP2(x,y));
}

void CLine::MoveTo(CDC* pDC, double x, double y, CRGB c)
{
	MoveTo(pDC,CP2(x,y,c));
}

void CLine::LineTo(CDC* pDC, CP2 p1, BOOL anti)  //anti控制直線是否進行反走樣
{
	
	P1=p1;
	CP2 p = P0;
	int dx = abs ( P1.x - P0.x );
	int dy = abs ( P1.y - P0.y );
	int s1 = P1.x > P0.x ? 1 : -1;
	int s2 = P1.y > P0.y ? 1 : -1;
	BOOL interchange = FALSE;
	if(dy>dx)
	{
		int temp=dx;
		dx=dy;
		dy=temp;
		interchange=TRUE;
	}
	if(anti==FALSE)                           //用Bresenham算法繪製走樣直線  利用對稱性並且對其去小數和去除法運算改進了代碼
	{
		int e=dy+dy-dx;
		for(int i=1;i<dx;i++)
		{
			pDC->SetPixelV(p.x,p.y,RGB(p.clr.r*255,p.clr.g*255,p.clr.b*255));
			if(e>0)
			{
				if(!interchange)
					p.y+=s2;
				else
					p.x+=s1;
				e-=dx+dx;
			}
			if(!interchange)
				p.x+=s1;
			else
				p.y+=s2;
			e+=dy+dy;
		}
	}
	else                                //繪製反走樣直線 利用了Wu反走樣算法
	{
		double s3 = P1.x > P0.x ? 1/((P1.y-P0.y)/(P1.x-P0.x)) : -1/((P1.y-P0.y)/(P1.x-P0.x));
		double s4 = P1.y > P0.y ? (P1.y-P0.y)/(P1.x-P0.x) : -(P1.y-P0.y)/(P1.x-P0.x);
		double e,a,b;
		double k=(P1.y-P0.y)/(P1.x-P0.x);
		if(!interchange)
			e=s4;
		else
			e=s3;
		for(int i=1;i<dx;i++)
		{
			a=p.x;
			b=p.y;
			CRGB c0=CRGB(e,e,e)*255;
			CRGB c1=CRGB(1.0-e,1.0-e,1.0-e)*255;
			pDC->SetPixelV(Round(p.x),Round(p.y),RGB(c0.r,c0.g,c0.b));
			if(!interchange)
				b=p.y+s2;
			else
				a=p.x+s1;
			pDC->SetPixelV(Round(a),Round(b),RGB(c1.r,c1.g,c1.b));	
			if(!interchange)
			{
				p.x+=s1;
				e+=s4*s1;
			}
			else
			{
				p.y+=s2;
				e+=s3*s2;
			}
			if(e>=1.0)
			{
				if(!interchange)
					p.y+=s2;
				else
					p.x+=s1;
				e--;
			}	
		}
	}
}

void CLine::LineTo(CDC* pDC, double x, double y, BOOL anti)
{
	LineTo(pDC,CP2(x,y),anti);
}

void CLine::LineTo(CDC* pDC, double x, double y, CRGB c, BOOL anti)
{
	LineTo(pDC,CP2(x,y,c),anti);
}
做了CP2 CRGB CLine類,將bresenham算法和wu反走樣算法都寫進了CLine類,利用對稱性對算法實現進行了些改進,可以通過參數控制繪製直線時是否需要反走樣


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章