首页 > 代码库 > 计算机图形学 绘制任意斜率的直线(1)

计算机图形学 绘制任意斜率的直线(1)

作者:卿笃军

原文地址:http://blog.csdn.net/qingdujun/article/details/40025917


本文演示,通过自己编写绘制直线函数(像素点填充),绘制任意斜率的直线。

1)创建CP2类

头文件:p2.h

// P2.h: interface for the CP2 class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_P2_H__85E77AD6_0704_4E12_8E74_5BE1744B3154__INCLUDED_)
#define AFX_P2_H__85E77AD6_0704_4E12_8E74_5BE1744B3154__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

//二维点类
class CP2  
{
public:
	CP2();
	CP2(double x,double y);
	virtual ~CP2();
public:         //方便访问,直接定义为共有
	double x;
	double y;
};

#endif // !defined(AFX_P2_H__85E77AD6_0704_4E12_8E74_5BE1744B3154__INCLUDED_)
实现文件:p2.cpp
// P2.cpp: implementation of the CP2 class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DrawLine.h"
#include "P2.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

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

CP2::CP2()
{
	x=0.0;
	y=0.0;
}

CP2::CP2(double x,double y)
{
	this->x=x;
	this->y=y;
}

CP2::~CP2()
{

}
2)创建CLine类

头文件:Line.h

// Line.h: interface for the CLine class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_LINE_H__8A91E283_F40D_4086_8BB8_7A9D9A6DB4D5__INCLUDED_)
#define AFX_LINE_H__8A91E283_F40D_4086_8BB8_7A9D9A6DB4D5__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "P2.h"
class CLine  
{
public:
	CLine();
	virtual ~CLine();
	void MoveTo(CP2 p0);	          //移动到指定位置
	void MoveTo(double x, double y);
	void LineTo(CP2 p1, CDC *pDC);    //绘制直线,不含终点
	void LineTo(double x, double y, CDC *pDC);
private:
	CP2 P0;      //起点
	CP2 P1;      //终点
};

#endif // !defined(AFX_LINE_H__8A91E283_F40D_4086_8BB8_7A9D9A6DB4D5__INCLUDED_)
实现文件:Line.cpp
// Line.cpp: implementation of the CLine class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DrawLine.h"
#include "Line.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
//////////////////////////////////////////////////////////////////////

CLine::CLine()
{

}

CLine::~CLine()
{

}

void CLine::MoveTo(CP2 p0) //记录直线起点函数
{	
	P0=p0;
}
void CLine::MoveTo(double x, double y)
{
	P0.x = x;
	P0.y = y;
}
void CLine::LineTo(double x, double y, CDC *pDC) //绘制
{
	CP2 p;
	p.x = x;
	p.y = y;

	LineTo(p, pDC);
}
void CLine::LineTo(CP2 p1, CDC *pDC)
{
	P1=p1;
	CP2 p,t;
	COLORREF clr = RGB(0,0,0);  //黑色像素点
	if(fabs(P0.x-P1.x)<1e-6)    //绘制垂线
	{
		if(P0.y>P1.y)           //交换顶点,使得起始点低于终点
		{
			t=P0;P0=P1;P1=t;
		}
		for(p=P0;p.y<P1.y;p.y++)  //执行绘制,填充像素点
		{
			pDC->SetPixelV(Round(p.x),Round(p.y),clr);	
		}
	}
	else
	{
		double k,d;
		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;
			}
			d=1-0.5*k;    //中点初始值
			for(p=P0;p.y<P1.y;p.y++)
			{
				pDC->SetPixelV(Round(p.x),Round(p.y), clr);
                if(d>=0)  //中点位于将绘制点上方,填充下方点
				{
					p.x++;
					d=d+1-k;    //递推公式:当d>=0时,d(i+1)=d(i)+1-k;
				}
				else 
                    d+=1;       
			}
		}
		if(0.0<=k && k<=1.0) //绘制0<=k<=1(x为主方向)
		{
			if(P0.x>P1.x)
			{
				t=P0;P0=P1;P1=t;
			}
			d=0.5-k;     //中点初始值
			for(p=P0;p.x<P1.x;p.x++)
			{
				pDC->SetPixelV(Round(p.x),Round(p.y), clr);
                if(d<0)  //中点位于将绘制点下方,填充上方点
				{
					p.y++;
					d=d+1-k; //递推公式:当d<0时,d(i+1)=d(i)+1-k;
				}
				else 
					d-=k;		
			}
		}		
		if(k>=-1.0 && k<0.0)//绘制-1<=k<0(x为主方向)
		{
			if(P0.x>P1.x)
			{
				t=P0;P0=P1;P1=t;
			}
			d=-0.5-k;        //中点初始化
            for(p=P0;p.x<P1.x;p.x++)
			{
				pDC->SetPixelV(Round(p.x),Round(p.y), clr);
                if(d>0)      //中点位于将绘制点上方,填充下方点
				{
					p.y--;
					d=d-1-k; //递推公式:当d>0时,d(i+1)=d(i)-1-k;
				}
				else 
					d-=k;		
			}
		}
		if(k<-1.0)//绘制k<-1 (y为主方向)
		{
			if(P0.y<P1.y)
			{
				t=P0;P0=P1;P1=t;
			}
			d=-1-0.5*k; //中点初始化
			for(p=P0;p.y>P1.y;p.y--)
			{
				pDC->SetPixelV(Round(p.x),Round(p.y), clr);
                if(d<0) //中点位于将绘制点下方,填充上方点
				{
					p.x++;
					d=d-1-k;//递推公式:当d>0时,d(i+1)=d(i)-1-k;
				}
				else 
					d-=1;           
			}
		}
	}
	P0=p1;  //将终点赋值给起点
}
3)OnDraw函数

void CDrawLineView::OnDraw(CDC* pDC)
{
	CDrawLineDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	//绘制直线
	CLine *line=new CLine;//动态创建直线绘制类对象
	line->MoveTo(100,100);
	line->LineTo(500,500, pDC);
}
4)绘制效果如下



原文地址:http://blog.csdn.net/qingdujun/article/details/40025917

参考文献:计算机图形学基础教程(Visual C++版)(第2版) 孔令德 编著


计算机图形学 绘制任意斜率的直线(1)