C++/MFC工程[4]——绘制直线段
一、MoveTo()函数和LineTo()函数
本文实例均于 ***View().cpp文件中的OnDraw()函数中实现。
两函数在上上节C++/MFC工程[2]——自定义平面直角坐标系中已经有所应用。
MoveTo()函数只设置起点,不画线。
LineTo()函数进行画线,画线结束后,起点变为LineTo()函数中的参数点,即本次画线的终点(以下实例中会体现,便于加深理解)。
//绘制起点为P0(10,10)、终点为P1(100,20)的直线
CDC* pDC = GetDC();
//一:定义两点P0,P1,传参画线
CPoint P0,P1;
P0=(10,10);
P1=(100,20);
pDC->MoveTo(P0);
pDC->LineTo(P1);
//二、直接传参横纵坐标
pDC->MoveTo(10,10);
pDC->LineTo(100,20);
二、画笔CPen类和画刷CBrush类
CPen和CBrush类都属于GDI工具类。CPen默认为1像素宽的黑色实线,CBrush默认为填充白色。二者在使用前要先选入设备上下文;使用后要恢复设备上下文。
1、创建画笔函数
CreatePen(int PenStyle, int PenWidth, PenColor),参数含义依次为:画笔样式、画笔宽度、画笔颜色。
画笔样式包括实线、虚线、点划线等,感兴趣的同学可自行搜索学习。
画笔颜色的表示方法有两种,详见C++/MFC第一篇(三、颜色表示的简单介绍)。
2、创建画刷函数
CreateSolidBrush(BrushColor),参数含义为:画刷颜色。
3、选入设备上下文
① 画笔
OldPen = pDC->SelectObject(&NewPen);
OldPen为原画笔指针,NewPen为新创建的画笔。
② 画刷
OldBrush = pDC->SelectObject(&NewBrush);
OldBrush为原画刷指针,NewBrush为新创建的画刷。
4、恢复设备上下文
① 画笔
pDC->SelectObject(OldPen);
pDC为CDC类指针,OldPen为原画笔指针。
② 画刷
pDC->SelectObject(OldBrush);
pDC为CDC类指针,OldBrush为原画刷指针。
三、实例
1、绘制三角形
//自定义坐标系下实现
//绘制顶点为p0,P1,P2的三角形
CPoint P0(-200, -100), P1(200, -100), P2(0, 200);
pDC->MoveTo(P0);
pDC->LineTo(P1);
pDC->LineTo(P2);
pDC->LineTo(P0);
运行结果如下:
注:自定义坐标系请于C++/MFC工程[2]——自定义平面直角坐标系 中查看。
2、根据要求绘制直线
要求:从P0到P1绘制1像素宽的绿色实线,从P1到P2绘制3像素宽的蓝色实线。
//自定义坐标系下实现
CPoint P0(-100, -100), P1(30, 20), P2(100, 150);
CPen greenPen, bluePen, * pOldPen; //OldPen用来保存原指针
greenPen.CreatePen(0, 1, RGB(0, 255, 0));//创建画笔,(样式,宽度,颜色)
pOldPen = pDC->SelectObject(&greenPen);//选入上下文
pDC->MoveTo(P0);
pDC->LineTo(P1);//当前位置保持在P1位置
pDC->SelectObject(pOldPen);//恢复上下文
bluePen.CreatePen(0, 3, RGB(0, 0, 255));//创建画笔,(样式,宽度,颜色)
pOldPen = pDC->SelectObject(&bluePen);//选入上下文
pDC->LineTo(P2);
pDC->SelectObject(pOldPen);//恢复上下文
运行结果如下:
注:LineTo 只保留起点颜色,不保留终点颜色,故P1点是蓝色的 。
3、绘制“金刚石”图案
金刚石——各顶点为某个圆上的等分点,各点之间均相连。
//自定义坐标系下实现
int r = 200, n = 12;//半径为200,等分为12份
CPoint P[12];
double Theta = 2 * PI / n;//等分角的角度
for (int i = 0; i < n; i++)
{
P[i].x = ROUND(r * cos(i * Theta));//计算坐标,宏ROUND将结果转换为整型变量
P[i].y = ROUND(r * sin(i * Theta));
}
for (int i = 0; i <= n - 2; i++)
{
for (int j = i + 1; j <= n - 1; j++)//连接各个点,避免线段的重复绘制
{
pDC->MoveTo(P[i]);
pDC->LineTo(P[j]);
}
}
注:ROUND宏定义为:#define ROUND(d) int(floor(d) + 0.5)
运行结果如下:
本例中将圆进行了12等分,修改n值与数组P大小,还可以得到如下结果:
如上,分别为十等分、十五等分的结果,具有对称美。不难发现,随着n值的增大,图形会更加趋向于圆。