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 
#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;iSetPixelV(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;iSetPixelV(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类,利用对称性对算法实现进行了些改进,可以通过参数控制绘制直线时是否需要反走样


你可能感兴趣的:(图形学学习篇)