基于MFC框架的OpenGL绘图:画直线(详解版)

文章目录

  • 前言
  • 一、前期准备
    • 1.成员变量
    • 2.鼠标响应事件
  • 二、正式画图
    • 1. 调用Display()函数
    • 2. 画网格
    • 3. 画线
    • 4. DDA算法
  • 总结


前言

这是上一篇文章的详解版本,容我和大家详细地分享一下画线思路
依然老鹅


一、前期准备

1.成员变量

	// 背景网格的间隔const float GRIDGAP = 0.1f;// 记录起始点CPoint startPoint;CPoint endPoint;// 判断绘图状态bool isDrawing;// 保存画好的线int lineCount;CPoint linePoints[1000][2];

2.鼠标响应事件

鼠标按下时,准备绘制当前线段。将isDrawing置为true,并记录起点位置。嗯……顺便把终点位置也放到那

void CMy22uCGv1View::OnLButtonDown(UINT nFlags, CPoint point)
{isDrawing = true;startPoint = point;endPoint = point;Invalidate(false);COpenGLView::OnLButtonDown(nFlags, point);
}

鼠标移动时,只要在画图,就让当前线段的尾部跟着移动

void CMy22uCGv1View::OnMouseMove(UINT nFlags, CPoint point)
{if (isDrawing) {endPoint = point;Invalidate(false);}COpenGLView::OnMouseMove(nFlags, point);
}

鼠标抬起时,结束绘制,并保存当前线段

void CMy22uCGv1View::OnLButtonUp(UINT nFlags, CPoint point)
{isDrawing = false;endPoint = point;linePoints[lineCount][0] = startPoint;linePoints[lineCount][1] = endPoint;lineCount++;Invalidate(false);COpenGLView::OnLButtonUp(nFlags, point);
}

二、正式画图

1. 调用Display()函数

我们所有的画图操作都会丢在这里面进行

void CMy22uCGv1View::Display()
{// 清空屏幕glClearColor(0.2f, 0.2f, 0.2f,1.0f);glClear(GL_COLOR_BUFFER_BIT);// 画网格DrawGrids();// 画线DrawLines();
}

2. 画网格

总之先把背景的网格画出来

void CMy22uCGv1View::DrawGrids()
{// 获取视口的宽高CRect rc;GetClientRect(rc);float width = rc.right - rc.left;float height = rc.bottom - rc.top;// 计算画线数量float wNum = (int)(width / height * 10) / 10.f;// 调好颜色开画// OpenGL坐标系见上一篇文章glColor3f(0.5f, 0.5f, 0.5f);glBegin(GL_LINES);for (float i = -wNum; i < wNum + 0.0001f; i += GRIDGAP)// 因为是float类型所以需要加上一个小值作误差// GRIDGAP是之前定义的浮点型常量{// 竖线glVertex2f(i, -1);glVertex2f(i, 1);}for (float i = -1; i < 1.0001f; i += GRIDGAP){// 横线glVertex2f(-wNum, i);glVertex2f(wNum, i);}glEnd();
}

画出来的效果就像这样:
网格背景

3. 画线

用OpenGL的glvertex方法画线。注意要把当前正在画的线(isDrawing为true)和已经画好的线都画出来

void CMy22uCGv1View::DrawLines()
{// 拖拽线glColor3f(0.95f, 0.95f, 0.95f);if (isDrawing){glBegin(GL_LINES);// 坐标转换glVertex2f(ChangePos(startPoint.x, 1), ChangePos(startPoint.y, 2));glVertex2f(ChangePos(endPoint.x, 1), ChangePos(endPoint.y, 2));// 不转换就看不见// glVertex2f(startPoint.x, startPoint.y);// glVertex2f(endPoint.x, endPoint.y);glEnd();}// 已画线for (int i = 0; i < lineCount; i++){float x0 = ChangePos(linePoints[i][0].x, 1);float y0 = ChangePos(linePoints[i][0].y, 2);float x1 = ChangePos(linePoints[i][1].x, 1);float y1 = ChangePos(linePoints[i][1].y, 2);// 把线画上glBegin(GL_LINES);glVertex2f(x0, y0);glVertex2f(x1, y1);glEnd();// DDA算法画圆DrawLine_DDA(x0, y0, x1, y1);}
}

这里大的来了,它就是——坐标变换
因为之前记录的startPoint和endPoint点都是屏幕坐标,随随便便就几十上百了,直接画会超出视口显示范围,导致啥也看不见,所以得先把它们转成视口坐标。这里是写了一个ChangePos()函数

float CMy22uCGv1View::ChangePos(float num, int mode) 
// 用mode判断这是x坐标还是y坐标
{float n = num;CRect rc;GetClientRect(rc);float width = rc.right - rc.left;float height = rc.top - rc.bottom;if (mode == 1) // n = n / width * 4.5376 - 2.2688;// n = -(n / width * width / height * 2 - width / height);n = (width - 2 * n) / height;else n = n / height * 2 + 1;return n;
}

现在就能看到我们辛辛苦苦画的线了
这线条多是一件美事啊

4. DDA算法

最后是用DDA算法沿线画圆。关于算法本身的介绍可以看上篇文章里贴的链接

void CMy22uCGv1View::DrawLine_DDA(float x0, float y0, float x1, float y1)
{float dx = x1 - x0;float dy = y1 - y0;float k = dy / dx;bool flag = false;if (k > 1 || k < -1) {flag = true;k = dx / dy;Swap(x0, y0, x1, y1);}// 起点调整,把圆心放在网格交点上float adjust = x0 >= 0 ? 1 : -1;float x = int(x0 / GRIDGAP + adjust * GRIDGAP * 5) * GRIDGAP;adjust = y0 >= 0 ? 1 : -1;float y = int(y0 / GRIDGAP + adjust * GRIDGAP * 5) * GRIDGAP;if (!flag)DrawCircle(x, y);elseDrawCircle(y, x);if (x0 <= x1) // 往右 {while (x < x1) {x += GRIDGAP;if (x > x1) {// 终点调整if (x1 < (x - 0.5f * GRIDGAP)) break;}y0 += k * GRIDGAP;if (k >= 0) {if (y0 >= y + GRIDGAP * 0.5f) {y += GRIDGAP;}}else {if (y0 <= y - GRIDGAP * 0.5f) {y -= GRIDGAP;}}if (!flag)DrawCircle(x, y);elseDrawCircle(y, x);}}else // 往左 {while (x > x1) {x -= GRIDGAP;if (x < x1) {// 终点调整if (x1 > (x + 0.5f * GRIDGAP)) break;}y0 -= k * GRIDGAP;if (k <= 0) {if (y0 >= y + GRIDGAP * 0.5f) {y += GRIDGAP;}}else {if (y0 <= y - GRIDGAP * 0.5f) {y -= GRIDGAP;}}if (!flag)DrawCircle(x, y);elseDrawCircle(y, x);}}
}

画圆的函数DrawCircle()长这样:

void CMy22uCGv1View::DrawCircle(float x, float y)
{glBegin(GL_TRIANGLE_FAN);for (int i = 0; i <= 360; i += 30) {float p = (float)(i * 3.14 / 180);glVertex2f(x + (float)sin(p) * GRIDGAP * 0.5f, y + (float)cos(p) * GRIDGAP * 0.5f);}glEnd();
}

交换坐标的函数Swap()长这样:

void CMy22uCGv1View::Swap(float &x0, float &x1, float &y0, float &y1)
{float tmp = x0;x0 = x1;x1 = tmp;tmp = y0;y0 = y1;y1 = tmp;
}

这下终于可以画出本文开头一样的效果了
听我说谢谢你


总结

这就是我在MFC框架中用OpenGL画线的全过程了,希望对你有帮助~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/53889.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Diagramme包画流程图

Diagramme包画流程图 library(DiagrammeR)# 1 -----------------------------------------------------------------------grViz("digraph flowchart {# node definitions with substituted label textnode [fontname Helvetica, shape rectangle] tab1 [label …

甘特图控件DHTMLX Gantt入门使用教程【引入】:dhtmlxGantt 与 ASP.NET MVC(下)

DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的大部分开发需求&#xff0c;具备完善的甘特图图表库&#xff0c;功能强大&#xff0c;价格便宜&#xff0c;提供丰富而灵活的JavaScript API接口&#xff0c;与各种服务器端技术&am…

甘特图控件DHTMLX Gantt入门使用教程【引入】:dhtmlxGantt 与 ASP.NET MVC(上)

DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的大部分开发需求&#xff0c;具备完善的甘特图图表库&#xff0c;功能强大&#xff0c;价格便宜&#xff0c;提供丰富而灵活的JavaScript API接口&#xff0c;与各种服务器端技术&am…

效果图底图 线框图_线框图初学者指南

效果图底图 线框图 线框图是任何屏幕设计过程中的重要一步。 它主要允许您定义设计的信息层次结构&#xff0c;从而使您可以轻松地根据希望用户处理信息的方式来规划布局。 如果您还没有使用线框图&#xff0c;是时候让您的脚湿了。 在开始之前&#xff0c;有一个简单的问题&a…

平面图,对偶图,

平面图定义&#xff1a; 图存在一种形式&#xff0c;所有的边只在顶点处相交&#xff0c;那么这个图就是平面图。 对偶图定义&#xff1a; 对于每一个平面图&#xff0c; 都有与其相对应的对偶图. 我们假设上面的例图是图G&#xff0c; 与其对应的对偶图G*&#xff0c; 那么对…

eplan图框制作

1、 首先&#xff0c;新建一个原理图项目 2、 新建图框。选择“工具”→“主数据”→“图框”→“新建” 在“文件名”中输入文件名&#xff0c;保存。 3、添加新建图框属性选项。选中“新建符号*”&#xff0c;添加选项 4、 设置图框的属性 a、 列/行字符数&#xff0c;设置为…

【WhatsApp营销】跨境电商推动销售和增长的 7 种方法

WhatsApp 如何帮助推动跨境电商销售&#xff1f;它提供什么样的跨境电商集成&#xff1f;在这篇文章中&#xff0c;我们将探讨跨境电商利用 WhatsApp 发展在线业务的七种方法。 鉴于 WhatsApp 的巨大影响力&#xff0c;与买家联系、营销和销售您的产品并最终在该平台上发展跨境…

关于这次寒武纪裁员的细节

寒武纪是一家看起来很神奇的公司&#xff0c;主营业务和智能芯片相关&#xff0c;今年的股价非常亮眼&#xff0c;年初到现在短短几个月&#xff0c;翻了四五倍。说实话有点小羡慕&#xff0c;要是年初买了它&#xff0c;现在估计也会说&#xff0c;寒武纪真牛皮&#xff0c;毕…

机器学习实战:Python基于支持向量机SVM-RFE进行分类预测(三)

文章目录 1 前言1.1 支持向量机的介绍1.2 支持向量机的应用 2 demo数据集演示2.1 导入函数2.2 构建数据集拟合2.3 预测模型及可视化 3 实例演示分类&#xff08;非SVM&#xff09;3.1 导入函数和数据3.2 简单线性分类3.3 最大间隔决定分类 4 实例演示分类&#xff08;SVM&#…

周期性分析

周期性分析就是探索某个变量是否随着时间的变化而呈现出周期性变化的趋势。具体的周期时间的选取可以根据情况而自定。 具体的代码展现如下&#xff1a; 我遇到的问题&#xff1a; 解决办法&#xff1a; 已解决SyntaxError: (unicode error) ‘unicodeescape’ codec can’t…

从0到1理解ChatGPT, GPT-4【文末送书】

作为一项人工智能技术&#xff0c;ChatGPT正在以飞快的速度向前发展&#xff0c;其强大的学习能力甚至可以用超乎想象来形容。 OpenAI公司带着最新的GPT-4开始“大杀四方”了~OpenAI推出GPT-4文本生成AI系统。紧随其后百度发布文心一言,开启智能对话新时代。&#xff08;文末送…

chatgpt赋能python:Python画图符号详解:入门必知的基础功能

Python画图符号详解&#xff1a;入门必知的基础功能 如果你是初学者&#xff0c;刚刚接触Python编程的话&#xff0c;你可能会感到一点无从下手。但是&#xff0c;随着你的学习深入&#xff0c;你会发现Python的一些非常有用的功能——如画图功能&#xff0c;非常实用又好玩。…

chatgpt赋能python:Python快速画图的不可替代性

Python快速画图的不可替代性 Python作为一个高级编程语言&#xff0c;在科学计算和数据处理领域已经越来越受欢迎。不仅如此&#xff0c;Python也拥有强大的图形库&#xff0c;使其成为一种快速、简便且便于部署的绘图方案。 1. Matplotlib 在Python的图形库中&#xff0c;M…

AIGC浪潮下裁员已至,谈谈居安思危

目录 1、创始人的裁员公告 2、18个月奇迹 3、ChatGPT终结了一切 4、大树之下寸草不生 6、任何一家企业都应居安思危 5、写在最后&#xff1a;既是风口也是浪尖 参考链接&#xff1a; 让所有人都没想到的是&#xff0c;正值人工智能之火烧遍全球之时&#xff0c;一家估值…

2月datawhale组队学习:大数据

文章目录 一、大数据概述二、 Hadoop2.1 Hadoop概述2.2 su:Authentication failure2.3 使用sudo命令报错xxx is not in the sudoers file. This incident will be reported.2.4 创建用户datawhale&#xff0c;安装java8&#xff1a;2.5 安装单机版Hadoop2.5.1 安装Hadoop2.5.2 …

这里有110+公开的专业数据集

&#x1f446;点击关注&#xff5c;设为星标&#xff5c;干货速递&#x1f446; 哈喽大家好&#xff0c;我是俊欣 如果你不是会爬虫的技术流&#xff0c;那下面这110网站可以解决你90%的数据需求。 首先&#xff0c;常见的公开数据网站在 https://hao.199it.com/ 都可以搜索到。…

基于Python的世界各个国家的幸福度的公开数据集的数据挖掘

目录 一&#xff0e; 问题背景 1 二&#xff0e; 准备工作 2 三&#xff0e; 具体实施 2 1.数据存储及基本加载 2 数据整理到数组之中 2 2.数据清洗 2 ① 多余列清除 2 ② 列属性归一 3 ③ 空值处理 4 3.数据挖掘算法 6 ① 基本特征 6 ② 总体热力图分析 7 ③ 对指定数据的热…

【博览群书】《实战大数据》——属于我的第一本大数据图书

文章目录 前言简介目录其他 前言 Hello家人们&#xff0c;博主前不久参加了CSDN图书馆和机械工业出版社联合举办的图书类活动&#xff0c;很荣幸在活动中获得了属于自己的第一本大数据图书&#xff0c;《实战大数据—— 分布式大数据分析处理系统开发与应用》。作为大数据专业…

大数据与AI的16个实践分享

↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习&#xff0c;不错过 Datawhale活动 主办方&#xff1a;DataFun&#xff0c;指导单位&#xff1a;北京智源研究院 文章作者&#xff1a;Hoh Xil 出品平台&#xff1a;DataFunTalk 导读&#xff1a;12.19-20&…

用最诙谐的语言提升你对大数据的认知

写在前面 本文隶属于专栏《100个问题搞定大数据理论体系》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见100个问题搞定大数据理论体系 引子 小明又来了~ …