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值的增大,图形会更加趋向于圆。

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陆小玖

您的鼓励是我的不竭动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值