⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pline.cpp

📁 这是我做的一个VC++小程序
💻 CPP
字号:
/////////////////////////////////////////////////////////////////////////////////
//	
// PLine.cpp: implementation of the CPLine class.
//
////////////////////////////////////////////////////////////////////////////////
// 版权所有(2002)
// Copyright(2002)
// 编写者: 向世明
// Author: Xiang Shiming

#include "stdafx.h"
#include "PLine.h"

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

CPLine::CPLine(){}

CPLine::~CPLine(){}

//该函数充分利用Window画笔进行绘制直线
//四个参数:
//pDC----设备描述表
//pt1----直线起点
//pt2----直线终点
//pen----直线颜色及线风格
//该函数只能绘制一条颜色相同的直线.

//注意, 对于 pt1 和 pt2 两个参数还可以接受CPoint对象

void CPLine::Draw(CDC *pDC,  POINT pt1,  POINT pt2,  CPen& pen)
{
	//选择画笔
	CPen* oldPen = pDC->SelectObject(&pen);
	//绘制直线
	pDC->MoveTo(pt1);
	pDC->LineTo(pt2);

	//选择原来的设备属性
	pDC->SelectObject(oldPen);
}

void CPLine::Draw(CDC *pDC,  int x1, int y1, int x2, int y2,  CPen& pen)
{
	//选择画笔
	CPen* oldPen = pDC->SelectObject(&pen);
	//绘制直线
	pDC->MoveTo(x1, y1);
	pDC->LineTo(x2, y2);//do not include the point (x2, y2)

	//选择原来的设备属性
	pDC->SelectObject(oldPen);
}


//绘制一条直线, 直线的宽度为1, 直线的颜色由直线两个端点的颜色共同决定
//注意, 对于 pt1 和 pt2 两个参数还可以接受CPoint对象
//注意, 浮点颜色的有效值为[0, 1]区间内的浮点小数

//与Windows相对应, 该算法也不包含最后一个点(x2, y2)
//注意, 从(x1, y1)--(x2, y2)与(x2, y2)--(x1, y1)略有些许不同.

//评价:该函数绘制的直线(像素位置)与Windows的LineTo()函数绘制的结果是完全一致的
void CPLine::Draw(CDC *pDC,  int x1, int y1, int x2, int y2,  FLOATCOLORRGB clr1,  FLOATCOLORRGB clr2)
{
	//两端点间的水平偏移量和垂直偏移量
	int nDx = x2 - x1;	
	int nDy = y2 - y1;

	//两端点间的水平距离和垂直距离
	int nIx = ABS(nDx);
	int nIy = ABS(nDy);

	//描点步数(增量总值)
	int nInc = MAX(nIx, nIy);

	//直线当前点的颜色
	float fPlotR = clr1.red,  fPlotG = clr1.green,  fPlotB = clr1.blue; 

	//绘制第一个点, 即, 直线的起点
	pDC->SetPixelV(x1, y1, RGB((BYTE)(fPlotR * 255.0f), (BYTE)(fPlotG * 255.0f), (BYTE)(fPlotB * 255.0f)));
	if(nInc < 2) return;

	//用于判断是否在nJudgeX, nJudgeY方向上向前进
	int nJudgeX = -nIy,  nJudgeY = -nIx;

	//通过增量计算得到的当前点
	int x = x1,  y = y1;
	
	//开始进行增量计算
	//采用Bresenham算法.在这里, 我们将算法进行改进, 
	//使其对于任意斜率的直线都能绘制, 而且绘制方向始终为从起点绘制到终点

	//与Windows相对应, 该算法也不包含最后一个点(x2, y2)
	nInc--;

	//注意, 整数乘2在计算机中采用移位实现
	//Bresenham算法
	int nTwoIx = 2 * nIx,  nTwoIy = 2 * nIy;

	//颜色增量
	float fIncR = (clr2.red - fPlotR) / nInc;
	float fIncG = (clr2.green - fPlotG) / nInc;
	float fIncB = (clr2.blue - fPlotB) / nInc;

	//开始增量计算
	for(int i = 0;i < nInc; i++)
	{
		nJudgeX += nTwoIx;
		nJudgeY += nTwoIy;

		//通过增量法计算的当前点是否属于直线上的点
		BOOL bPlot = FALSE;

		//检测 nJudgeX 方向
		if(nJudgeX >= 0)
		{
			bPlot = TRUE;
			nJudgeX -= nTwoIy;

			//将任意走向的直线统一起来
			if(nDx > 0)x++;
			else if(nDx < 0)x--;
		}

		//检测 nJudgeY 方向
		if(nJudgeY >= 0)
		{
			bPlot = TRUE;
			nJudgeY -= nTwoIx;

			//将任意走向的直线统一起来
			if(nDy > 0)y++;
			else if(nDy < 0)y--;
		}
		//如果当前点在直线上
		if(bPlot)
		{
			fPlotR += fIncR;
			fPlotG += fIncG;
			fPlotB += fIncB;

			//绘制当前点
			pDC->SetPixelV(x, y, 
				RGB((BYTE)(fPlotR * 255.0f), (BYTE)(fPlotG * 255.0f), (BYTE)(fPlotB * 255.0f)));
		}//end if
	}//end for
}

//采用Bresenham算法绘制一条颜色渐变的直线
void CPLine::Draw(CDC *pDC,  POINT pt1,  POINT pt2,  FLOATCOLORRGB clr1,  FLOATCOLORRGB clr2)
{
	//两端点坐标
	int x1 = pt1.x,  y1 = pt1.y;
	int x2 = pt2.x,  y2 = pt2.y;
	Draw(pDC, x1, y1, x2, y2, clr1, clr2);
}

//采用Bresenham算法绘制一条颜色相同的直线
//将Bresenham算法写成统一的形式
//x1, y1, x2, y2直线的起点和端点
void CPLine::Draw(CDC *pDC,  int x1, int y1, int x2, int y2,  COLORREF clr)
{
	//两端点间的水平偏移量和垂直偏移量
	int nDx = x2 - x1;	
	int nDy = y2 - y1;

	//两端点间的水平距离和垂直距离
	int nIx = ABS(nDx);
	int nIy = ABS(nDy);

	//描点步数(增量总值)
	int nInc = MAX(nIx, nIy);
	
	//绘制第一个点, 即, 直线的起点
	pDC->SetPixelV(x1, y1, clr);
	
	//不包含终点
	if(nInc < 2)return;

	//用于判断是否在nJudgeX, nJudgeY方向上向前进
	int nJudgeX = -nIy,  nJudgeY = -nIx;

	//通过增量计算得到的当前点
	int x = x1,  y = y1;
	
	//开始进行增量计算
	//采用Bresenham算法.在这里, 我们将算法进行改进, 
	//使其对于任意斜率的直线都能绘制, 而且绘制方向始终为从起点绘制到终点

	//注意, 整数乘2在计算机中采用移位实现
	//Bresenham算法
	int nTwoIx = 2 * nIx,  nTwoIy = 2 * nIy;

	//与Windows相对应, 该算法也不包含最后一个点(x2, y2)
	nInc--;

	//开始增量计算
	for(int i = 0;i < nInc; i++)
	{
		nJudgeX += nTwoIx;
		nJudgeY += nTwoIy;

		//通过增量法计算的当前点是否属于直线上的点
		BOOL bPlot = FALSE;

		//检测 X 方向
		if(nJudgeX >= 0)
		{
			bPlot = TRUE;
			nJudgeX -= nTwoIy;

			//将任意走向的直线统一起来
			if(nDx > 0)x++;
			else if(nDx < 0)x--;
		}

		//检测 Y 方向
		if(nJudgeY >= 0)
		{
			bPlot = TRUE;
			nJudgeY -= nTwoIx;

			//将任意走向的直线统一起来
			if(nDy > 0)y++;
			else if(nDy < 0)y--;
		}
		//如果当前点在直线上, 则绘制当前点
		if(bPlot) pDC->SetPixelV(x, y, clr);
	}//end for
}

//采用Bresenham算法(统一表示)
void CPLine::Draw(CDC *pDC,  POINT pt1,  POINT pt2,  COLORREF clr)
{
	int x1 = pt1.x,  y1= pt1.y,  x2 = pt2.x,  y2 = pt2.y;
	Draw(pDC, x1, y1, x2, y2, clr);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -