当前位置: 首页 > news >正文

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

相关文章:

  • 人民大学与加拿大女王大学金融硕士——你终究会成为你想成为的人
  • 动静态库的制作
  • Python入门(4)语法、变量和标识符、数据类型、字符串、布尔值、类型检查、对象、类型转换、运算符
  • 接收机中的非线性因素来源与模型
  • 统计字典序元音字符串的数目 (回溯/dfs/动态规划/压缩/数学)
  • 5个python常用的装饰器!
  • OpenFeign 源码解读:动态代理+负载均衡实现
  • Java Web应用开发——作业四
  • 什么是谷歌快排技术,谷歌排名推广霸屏的原理
  • 01 | Qt基本介绍及环境搭建
  • FreeRTOS任务之调度器中的三种调度算法
  • 程序入参调优【自我提升】
  • 数据结构与算法(基于<algorithm>)
  • 【Linux】树状目录结构
  • [前端笔记038]vue2之vueRouter、elementUI
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • 11111111
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • 345-反转字符串中的元音字母
  • C# 免费离线人脸识别 2.0 Demo
  • CODING 缺陷管理功能正式开始公测
  • css选择器
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  • express.js的介绍及使用
  • laravel with 查询列表限制条数
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • Python socket服务器端、客户端传送信息
  • redis学习笔记(三):列表、集合、有序集合
  • scrapy学习之路4(itemloder的使用)
  • select2 取值 遍历 设置默认值
  • 关于springcloud Gateway中的限流
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 前端知识点整理(待续)
  • 手写一个CommonJS打包工具(一)
  • 线上 python http server profile 实践
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • Salesforce和SAP Netweaver里数据库表的元数据设计
  • 第二十章:异步和文件I/O.(二十三)
  • #Linux(make工具和makefile文件以及makefile语法)
  • #我与Java虚拟机的故事#连载18:JAVA成长之路
  • (C语言)二分查找 超详细
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (翻译)terry crowley: 写给程序员
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (三十五)大数据实战——Superset可视化平台搭建
  • (十五)Flask覆写wsgi_app函数实现自定义中间件
  • (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
  • (转)Sublime Text3配置Lua运行环境
  • .gitattributes 文件
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .net 4.0发布后不能正常显示图片问题