标签:des style blog http color io ar for strong
作者:卿笃军
原文地址:http://blog.csdn.net/qingdujun/article/details/40083207
本文通过一个完整的例子来演示彩色直线段的反走样。
1)创建CP2类
头文件:P2.h
// P2.h: interface for the CP2 class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_P2_H__DD23884F_7F62_48E8_A906_65C4558DE4EB__INCLUDED_)
#define AFX_P2_H__DD23884F_7F62_48E8_A906_65C4558DE4EB__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "RGB.h"
//二维点类
class CP2
{
public:
CP2();
CP2(double x,double y, CRGB c);
virtual ~CP2();
public: //方便访问,直接定义为共有
double x;
double y;
CRGB c;
};
#endif // !defined(AFX_P2_H__DD23884F_7F62_48E8_A906_65C4558DE4EB__INCLUDED_)
实现文件:P2.cpp
// P2.cpp: implementation of the CP2 class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "WuLine.h"
#include "P2.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CP2::CP2()
{
}
CP2::CP2(double x,double y, CRGB c)
{
this->x = x;
this->y = y;
this->c = c;
}
CP2::~CP2()
{
}
2)创建CRGB类
头文件:RGB.h
// RGB.h: interface for the CRGB class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_RGB_H__F163CE21_A4E9_4B66_9011_3B63D6E588D2__INCLUDED_)
#define AFX_RGB_H__F163CE21_A4E9_4B66_9011_3B63D6E588D2__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CRGB
{
public:
CRGB();
CRGB(double r,double g,double b);
virtual ~CRGB();
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);public:
public:
double red; //红色分量
double green; //绿色分量
double blue; //蓝色分量
};
#endif // !defined(AFX_RGB_H__F163CE21_A4E9_4B66_9011_3B63D6E588D2__INCLUDED_)
实现文件:RGB.cpp
// RGB.cpp: implementation of the CRGB class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "WuLine.h"
#include "RGB.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CRGB::CRGB()
{
red=1.0;
green=1.0;
blue=1.0;
}
CRGB::~CRGB()
{
}
CRGB::CRGB(double r,double g,double b)//重载构造函数
{
red=r;
green=g;
blue=b;
}
CRGB operator +(const CRGB &c1,const CRGB &c2)//+运算符重载
{
CRGB c;
c.red=c1.red+c2.red;
c.green=c1.green+c2.green;
c.blue=c1.blue+c2.blue;
return c;
}
CRGB operator -(const CRGB &c1,const CRGB &c2)//-运算符重载
{
CRGB c;
c.red=c1.red-c2.red;
c.green=c1.green-c2.green;
c.blue=c1.blue-c2.blue;
return c;
}
CRGB operator *(const CRGB &c1,const CRGB &c2)//*运算符重载
{
CRGB c;
c.red=c1.red*c2.red;
c.green=c1.green*c2.green;
c.blue=c1.blue*c2.blue;
return c;
}
CRGB operator *(const CRGB &c1,double k)//*运算符重载
{
CRGB c;
c.red=k*c1.red;
c.green=k*c1.green;
c.blue=k*c1.blue;
return c;
}
CRGB operator *(double k,const CRGB &c1)//*运算符重载
{
CRGB c;
c.red=k*c1.red;
c.green=k*c1.green;
c.blue=k*c1.blue;
return c;
}
CRGB operator /(const CRGB &c1,double k)// /运算符重载
{
CRGB c;
c.red=c1.red/k;
c.green=c1.green/k;
c.blue=c1.blue/k;
return c;
}
CRGB operator +=(CRGB &c1,CRGB &c2)//+=运算符重载
{
c1.red=c1.red+c2.red;
c1.green=c1.green+c2.green;
c1.blue=c1.blue+c2.blue;
return c1;
}
CRGB operator -=(CRGB &c1,CRGB &c2)//-=运算符重载
{
c1.red=c1.red-c2.red;
c1.green=c1.green-c2.green;
c1.blue=c1.blue-c2.blue;
return c1;
}
CRGB operator *=(CRGB &c1,CRGB &c2)//*=运算符重载
{
c1.red=c1.red*c2.red;
c1.green=c1.green*c2.green;
c1.blue=c1.blue*c2.blue;
return c1;
}
CRGB operator /=(CRGB &c1,double k)///=运算符重载
{
c1.red=c1.red/k;
c1.green=c1.green/k;
c1.blue=c1.blue/k;
return c1;
}
3)创建CWuAnti类// WuAnti.h: interface for the CWuAnti class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_WUANTI1_H__2C2D354F_C8AA_4F64_81CC_56195DEE5704__INCLUDED_)
#define AFX_WUANTI1_H__2C2D354F_C8AA_4F64_81CC_56195DEE5704__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "P2.h"
class CWuAnti
{
public:
CWuAnti();
virtual ~CWuAnti();
void MoveTo(double x, double y, CRGB c); //移动到指定位置,指定起点颜色
void MoveTo(CP2 p0);
void LineTo(CDC *pDC, double x, double y, CRGB c); //绘制Wu反走样直线,不含终点,指定终点颜色
void LineTo(CDC *pDC, CP2 p1);
private:
CP2 P0; //起点
CP2 P1; //终点
};
#endif // !defined(AFX_WUANTI1_H__2C2D354F_C8AA_4F64_81CC_56195DEE5704__INCLUDED_)
实现文件:WuAnti.cpp
// WuAnti.cpp: implementation of the CWuAnti class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "WuLine.h"
#include "WuAnti.h"
#include "RGB.h"
#include <math.h>
#define Round(d) int(floor(d+0.5))//四舍五入宏定义
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CWuAnti::CWuAnti()
{
}
CWuAnti::~CWuAnti()
{
}
void CWuAnti::MoveTo(double x, double y, CRGB c) //绘制彩色线条,指定起点颜色
{
P0.x=x;
P0.y=y;
P0.c=c;
}
void CWuAnti::MoveTo(CP2 p0) //绘制彩色线条
{
P0=p0;
}
void CWuAnti::LineTo(CDC *pDC, double x, double y, CRGB c) //绘制,指定终点颜色
{
LineTo(pDC, CP2(x, y, c));
}
void CWuAnti::LineTo(CDC *pDC, CP2 p1)
{
P1=p1;
CP2 p,t;
CRGB c0,c1;
//COLORREF Cf,Cb = pDC->GetBkColor();
if(fabs(P0.x-P1.x)==0)//绘制垂线
{
if(P0.y>P1.y)//交换顶点,使得起始点低于终点顶点
{
t=P0;P0=P1;P1=t;
}
for(p=P0;p.y<P1.y;p.y++)
{
//线性插值:c=(1-t)c0+tc1, t=(x-x0)/(x1-x0)或t=(y-y0)/(y1-y0)
// ------>c=c0+t(c1-c0)
p.c=P0.c+(P1.c-P0.c)*(p.y-P0.y)/(p1.y-P0.y); //重载RGB,‘+’‘-’‘*’‘/’运算符
pDC->SetPixelV(Round(p.x),Round(p.y),RGB(p.c.red,p.c.green,p.c.blue));
}
}
else
{
double k,e=0;
k=(P1.y-P0.y)/(P1.x-P0.x);
if(k>1.0)//绘制k>1 (y为主方向)
{
if(P0.y>P1.y)
{
t=P0;P0=P1;P1=t;
}
for(p=P0;p.y<P1.y;p.y++)
{
//像素亮度级别
c0=CRGB(e,e,e);
c1=CRGB(1.0-e,1.0-e,1.0-e);
//线性插值:c=(1-t)c0+tc1, t=(x-x0)/(x1-x0)或t=(y-y0)/(y1-y0)
p.c=P0.c+(P1.c-P0.c)*(p.y-P0.y)/(p1.y-P0.y);
pDC->SetPixelV(Round(p.x),Round(p.y),RGB(c0.red*p.c.red,c0.green*p.c.green,c0.blue*p.c.blue));
pDC->SetPixelV(Round(p.x+1),Round(p.y),RGB(c1.red*p.c.red,c1.green*p.c.green,c1.blue*p.c.blue));
e+=(1.0/k);
if(e>=1.0)
{
p.x++;
e--;
}
}
}
if(0.0<=k && k<=1.0)//绘制0=<k=<1 (x为主方向)
{
if(P0.x>P1.x)
{
t=P0;P0=P1;P1=t;
}
for(p=P0;p.x<P1.x;p.x++)
{
c0=CRGB(e,e,e);
c1=CRGB(1.0-e,1.0-e,1.0-e);
p.c=P0.c+(P1.c-P0.c)*(p.x-P0.x)/(p1.x-P0.x);
pDC->SetPixelV(Round(p.x),Round(p.y),RGB(c0.red*p.c.red,c0.green*p.c.green,c0.blue*p.c.blue));
pDC->SetPixelV(Round(p.x),Round(p.y+1),RGB(c1.red*p.c.red,c1.green*p.c.green,c1.blue*p.c.blue));
e=e+k;
if(e>=1.0)
{
p.y++;
e--;
}
}
}
if(k>=-1.0 && k<0.0)//绘制-1=<k<0 (x为主方向)
{
if(P0.x>P1.x)
{
t=P0;P0=P1;P1=t;
}
for(p=P0;p.x<P1.x;p.x++)
{
c0=CRGB(e,e,e);
c1=CRGB(1.0-e,1.0-e,1.0-e);
p.c=P0.c+(P1.c-P0.c)*(p.x-P0.x)/(p1.x-P0.x);
pDC->SetPixelV(Round(p.x),Round(p.y),RGB(c0.red*p.c.red,c0.green*p.c.green,c0.blue*p.c.blue));
pDC->SetPixelV(Round(p.x),Round(p.y-1),RGB(c1.red*p.c.red,c1.green*p.c.green,c1.blue*p.c.blue));
e=e-k;
if(e>=1.0)
{
p.y--;
e--;
}
}
}
if(k<-1.0)//绘制k<-1 (y为主方向)
{
if(P0.y<P1.y)
{
t=P0;P0=P1;P1=t;
}
for(p=P0;p.y>P1.y;p.y--)
{
c0=CRGB(e,e,e);
c1=CRGB(1.0-e,1.0-e,1.0-e);
p.c=P0.c+(P1.c-P0.c)*(p.y-P0.y)/(p1.y-P0.y);
pDC->SetPixelV(Round(p.x),Round(p.y),RGB(c0.red*p.c.red,c0.green*p.c.green,c0.blue*p.c.blue));
pDC->SetPixelV(Round(p.x+1),Round(p.y),RGB(c1.red*p.c.red,c1.green*p.c.green,c1.blue*p.c.blue));
e=e-1/k;
if(e>=1.0)
{
p.x++;
e--;
}
}
}
}
P0=p1;
}4)OnDraw函数
void CWuLineView::OnDraw(CDC* pDC)
{
CWuLineDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// 设置绘图坐标系:原点为View视图区域中心,X轴正向水平向右,Y轴正向垂直向上
CRect rect;
GetClientRect(&rect);//获得客户区矩形的大小
pDC->SetMapMode(MM_ANISOTROPIC); //自定义坐标系
pDC->SetWindowExt(rect.Width(),rect.Height()); //设置窗口比例
pDC->SetViewportExt(rect.Width(),-rect.Height()); //设置视区比例,且x轴向右,y轴向上
pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);//设置客户区中心为坐标系原点
rect.OffsetRect(-rect.Width()/2,-rect.Height()/2); //矩形与客户区重合
CWuAnti *line=new CWuAnti;//动态创建直线绘制类对象
line->MoveTo(100,-200,CRGB(255,0,0));
line->LineTo(pDC,100,200,CRGB(0,255,0));
//0<=k<=1
line->MoveTo(-206,-137,CRGB(255,0,0));
line->LineTo(pDC,214,175,CRGB(0,255,0));
//k>1
line->MoveTo(-201,-253,CRGB(255,0,0));
line->LineTo(pDC,201,266,CRGB(0,255,0));
//k<-1
line->MoveTo(-186,293,CRGB(255,0,0));
line->LineTo(pDC,201,-236,CRGB(0,255,0));
//-1<k<0
line->MoveTo(-286,193,CRGB(255,0,0));
line->LineTo(pDC,221,-246,CRGB(0,255,0));
}5)运行效果(放大25倍)
原文地址:http://blog.csdn.net/qingdujun/article/details/40083207
参考文献:计算机图形学基础教程(Visual C++版)(第2版) 孔令德 编著
百度文库,人生憶夢贡献,Wu反走样直线算法:http://wenku.baidu.com/link?url=6Nqvs2eaZTf9XrEXL7siH0bZOkfEk3W2OYM33Lo4ItYbA68Q1bquvCqt5O-BsJVxts8AKvBXgnx_qi_X1Ys7kG9wlcO8zGgq7JBXE8tdr6a
标签:des style blog http color io ar for strong
原文地址:http://blog.csdn.net/qingdujun/article/details/40083207