Qt OpenGL - 网格式的直角坐标系

Qt OpenGL - 网格式的直角坐标系

  • 引言
  • 一、绘制3D网格
    • 1.1 绘制平行于y轴的线段
    • 1.2 绘制平行于三个轴的线段
    • 1.3 绘制不同的3D网格
  • 二、网格式的直角坐标系
  • 三、参考链接

引言

在这里插入图片描述
在OpenGL进行3D可视化,只绘制三条坐标轴略显单薄,而绘制网格形式的坐标系则能更清晰的展示所画图形位置,如上图所示。

OpenGL可视化须知1:https://blog.csdn.net/sinat_36772813/article/details/129338953 OpenGL中的坐标系
OpenGL三维坐标系例子-只有三个轴2:https://blog.csdn.net/qq_37996632/article/details/103178120 OpenGL画坐标系2
OpenGL三维坐标系例子-网格形式3:https://blog.csdn.net/qq_40004575/article/details/109547793 Qt+OpenGL绘制三维坐标系(动态曲线显示)

一、绘制3D网格

paintGL()函数:

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除屏幕和深度缓存
    glLoadIdentity();

    //旋转显示窗口
    glTranslatef(0, 0, -30);
    //glRotatef(45, 0, 1, 0);

    //画3D网格
    std::vector<float> p1 = {-4.0f, -4.0f, -4.0f}, p2 = {4.0f, 4.0f, 4.0f};
    GL3DGrid(p1, p2, 3);

1.1 绘制平行于y轴的线段

在这里插入图片描述

  • 先绘制平行于y轴的线段,效果如上图,算法核心思想:
    给定两个3D坐标,要通过其绘制平行于y轴的若干线段,保证每个线段首尾点的x和z坐标是一致的,首尾点的y坐标即两个3D坐标的y坐标。
void QtDraw3DCtrl::GL3DGrid(std::vector<float> p1, std::vector<float> p2, int num)
{
    if(p1.size() !=3 || p2.size() !=3){
        return; // 稳健
    }
    num = num -1;
    const float _xLen = (p2[0] - p1[0]) / num;
    const float _yLen = (p2[1] - p1[1]) / num;
    const float _zLen = (p2[2] - p1[2]) / num;

    // 绘制参数
    glLineWidth(0.1f);
    glBegin(GL_LINES);
    glEnable(GL_LINE_SMOOTH);

    // 绘制平行于某轴的线段 比如y轴 y坐标固定从p1到p2  x,z坐标变换(无脑遍历即可)
    for (int xi = 0; xi <= num; xi++) {
        float x = _xLen * xi + p1[0];
        for (int zi = 0; zi <= num; zi++) {
            float z = _zLen * zi + p1[2];
            glVertex3f(x, p1[1], z);
            glVertex3f(x, p2[1], z);
        }
    }
    glEnd();
}

1.2 绘制平行于三个轴的线段

在这里插入图片描述

  • 绘制平行于三个轴的线段,如上图所示。增加绘制平行于x轴和z轴的线段,代码与绘制平行于y轴的线段类似,只是改几个参数。
void QopenGLDemo::GL3DGrid(std::vector<float> p1, std::vector<float> p2, int num)
{
    if(p1.size() !=3 || p2.size() !=3){
        return; // 稳健
    }
    num = num -1;
    const float _xLen = (p2[0] - p1[0]) / num;
    const float _yLen = (p2[1] - p1[1]) / num;
    const float _zLen = (p2[2] - p1[2]) / num;

    // 绘制参数
    glLineWidth(0.1f);
    glBegin(GL_LINES);
    glEnable(GL_LINE_SMOOTH);

    // 绘制平行y轴的线段 y坐标固定从p1到p2  x,z坐标变换(无脑遍历即可)
    for (int xi = 0; xi <= num; xi++) {
        float x = _xLen * xi + p1[0];
        for (int zi = 0; zi <= num; zi++) {
            float z = _zLen * zi + p1[2];
            glVertex3f(x, p1[1], z);
            glVertex3f(x, p2[1], z);
        }
    }

    // 绘制平行x轴的线段 x坐标固定从p1到p2  y,z坐标变换(无脑遍历即可)
    for (int yi = 0; yi <= num; yi++) {
        float y = _yLen * yi + p1[1];
        for (int zi = 0; zi <= num; zi++) {
            float z = _zLen * zi + p1[2];
            glVertex3f(p1[0], y, z);
            glVertex3f(p2[1], y, z);
        }
    }

    // 绘制平行z轴的线段 z坐标固定从p1到p2  x,y坐标变换(无脑遍历即可)
    for (int xi = 0; xi <= num; xi++) {
        float x = _xLen * xi + p1[0];
        for (int yi = 0; yi <= num; yi++) {
            float y = _yLen * yi + p1[1];
            glVertex3f(x, y, p1[2]);
            glVertex3f(x, y, p2[2]);
        }
    }

    // 结束绘制
    glEnd();
}

1.3 绘制不同的3D网格

在这里插入图片描述 在这里插入图片描述在这里插入图片描述

  • 修改GL3DGrid(p1, p2, 3)最后一个参数为4,6,10;

二、网格式的直角坐标系

在这里插入图片描述

  • 由以上代码已可绘制3D网格,但如果在其中绘制目标模型会被遮挡。故,可绘制3个2D网格方便显示,效果如上图所示。(写到这,发现一个bug,之前代码在绘制平行x轴的线段的时候,p2[1]应改为p2[0]) 核心源码如下所示:
void QopenGLDemo::paintGL(){
    // 初始化
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除屏幕和深度缓存
    glLoadIdentity();

    //旋转显示窗口
    glTranslatef(0, 0, -30);
    //glRotatef(45, 0, 1, 0);

    //画3D直角坐标系
    std::vector<float> x1 = {-4.0f, -4.0f, -4.0f}, x2 = {-4.0f, 4.0f, 4.0f};
    GL3DGrid(x1, x2, 10);

    std::vector<float> y1 = {-4.0f, -4.0f, -4.0f}, y2 = {4.0f, -4.0f, 4.0f};
    GL3DGrid(y1, y2, 10);

    std::vector<float> z1 = {-4.0f, -4.0f, -4.0f}, z2 = {4.0f, 4.0f, -4.0f};
    GL3DGrid(z1, z2, 10);
}

void QopenGLDemo::GL3DGrid(std::vector<float> p1, std::vector<float> p2, int num)
{
    if(p1.size() !=3 || p2.size() !=3){
        return; // 稳健
    }
    num = num -1;
    const float _xLen = (p2[0] - p1[0]) / num;
    const float _yLen = (p2[1] - p1[1]) / num;
    const float _zLen = (p2[2] - p1[2]) / num;

    // 绘制参数
    glLineWidth(0.1f);
    glBegin(GL_LINES);
    glEnable(GL_LINE_SMOOTH);

    // 绘制平行y轴的线段 y坐标固定从p1到p2  x,z坐标变换(无脑遍历即可)
    for (int xi = 0; xi <= num; xi++) {
        float x = _xLen * xi + p1[0];
        for (int zi = 0; zi <= num; zi++) {
            float z = _zLen * zi + p1[2];
            glVertex3f(x, p1[1], z);
            glVertex3f(x, p2[1], z);
        }
    }

    // 绘制平行x轴的线段 x坐标固定从p1到p2  y,z坐标变换(无脑遍历即可)
    for (int yi = 0; yi <= num; yi++) {
        float y = _yLen * yi + p1[1];
        for (int zi = 0; zi <= num; zi++) {
            float z = _zLen * zi + p1[2];
            glVertex3f(p1[0], y, z);
            glVertex3f(p2[0], y, z);
        }
    }

    // 绘制平行z轴的线段 z坐标固定从p1到p2  x,y坐标变换(无脑遍历即可)
    for (int xi = 0; xi <= num; xi++) {
        float x = _xLen * xi + p1[0];
        for (int yi = 0; yi <= num; yi++) {
            float y = _yLen * yi + p1[1];
            glVertex3f(x, y, p1[2]);
            glVertex3f(x, y, p2[2]);
        }
    }

    // 结束绘制
    glEnd();
}

三、参考链接


  1. https://blog.csdn.net/sinat_36772813/article/details/129338953 OpenGL中的坐标系 ↩︎

  2. https://blog.csdn.net/qq_37996632/article/details/103178120 OpenGL画坐标系2 ↩︎

  3. https://blog.csdn.net/qq_40004575/article/details/109547793 Qt+OpenGL绘制三维坐标系(动态曲线显示) ↩︎

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flutter之运行错误:this and base files have different roots

运行时报错&#xff1a; this and base files have different roots: E:\Demolpro\waqu\build\flutter-plugin-_android_lifecycle and C:\Users\78535\AppData\Local\Pub\Cache\hosted\pub.dev\flutter_pulgin_android_lifecycle-2.0.17\android 如图&#xff1a; 这种情况…

自制数据库空洞率清理工具-C版-03-EasyClean-V1.2(支持南大通用数据库Gbase8a)

目录 一、环境信息 二、简述 三、升级点 四、支持功能 五、空洞率 六、工具流程图 1、流程描述 2、注意点 &#xff08;1&#xff09;方法一 &#xff08;2&#xff09;方法二 七、清理空洞率流程图 八、安装包下载地址 九、参数介绍 1、命令模板 2、命令样例 3…

Pytest测试 —— 如何使用属性来标记测试函数!

在软件开发领域&#xff0c;单元测试是确保代码质量和可维护性的关键一环。随着项目的不断发展&#xff0c;测试用例的管理变得愈发复杂&#xff0c;而一些测试可能需要特殊的处理、环境或者标记。在Python中&#xff0c;我们可以通过使用属性&#xff08;Attribute&#xff09…

Leetcode202快乐数(java实现)

今天分享的题目是快乐数&#xff1a; 快乐数的定义如下&#xff1a; 快乐数&#xff08;Happy Number&#xff09;是指一个正整数&#xff0c;将其替换为各个位上数字的平方和&#xff0c;重复这个过程直到最后得到的结果为1&#xff0c;或者无限循环但不包含1。如果最终结果为…

层次选择器

层次选择器 1.后代选择器二、子代选择器三、兄弟选择器四、相邻选择器 后代选择器&#xff0c;选择M元素内部后代的N元素&#xff08;所有N元素&#xff09; 选择器说明M N后代选择器&#xff0c;选择M元素内部后代的N元素&#xff08;所有N元素M>N子代选择器&#xff0c;选…

MATLAB 2023a软件下载安装教程

编程如画&#xff0c;我是panda&#xff01; 这次给大家带来的是MATLAB 2023a的下载安装教程 前言 MATLAB&#xff0c;即Matrix Laboratory的缩写&#xff0c;是一款强大的科学计算软件&#xff0c;以其独特的矩阵计算基础、丰富的数学函数库和直观的数据可视化工具而闻名。作…

神经辐射场(NeRF)概述

神经辐射场&#xff08;NeRF&#xff09;是一种用于三维场景重建的深度学习算法。它能够从一组稀疏的二维图片中重建出高质量的三维场景。 以下是对NeRF算法的原理和实现方法的详细解释&#xff1a; NeRF算法原理&#xff1a; 基本概念&#xff1a; NeRF算法基于光线追踪的原理…

BSC/平衡记分卡

一、Balanced Score Card BSC即平衡计分卡&#xff08;Balanced Score Card&#xff09;&#xff0c;是常见的绩效考核方式之一&#xff0c;是从财务、客户、内部运营、学习与成长四个角度&#xff0c;将组织的战略落实为可操作的衡量指标和目标值的一种新型绩效管理体系。 是…

数据结构第十三弹---链式二叉树基本操作(上)

链式二叉树 1、结构定义2、手动创建二叉树3、前序遍历4、中序遍历5、后序遍历6、层序遍历7、计算结点个数8、计算叶子结点个数9、计算第K层结点个数10、计算树的最大深度总结 1、结构定义 实现一个数据结构少不了数据的定义&#xff0c;所以第一步需要定义二叉树的机构。 typ…

龙芯3A5000上使用腾讯会议

原文链接&#xff1a;龙芯3A5000上使用腾讯会议 hello&#xff0c;大家好啊&#xff01;今天我要给大家介绍的是在龙芯3A5000处理器上安装使用腾讯会议的经验分享。随着远程工作和在线会议的普及&#xff0c;腾讯会议成为了许多人日常工作不可或缺的工具。而对于使用龙芯3A5000…

HTTP 常见协议:选择正确的协议,提升用户体验(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

Docker 镜像

1、联合文件系统 UnionFS&#xff08;联合文件系统)&#xff1a;Union文件系统〈UnionFS)是一种分层、轻量级并且高性能的文件系统&#xff0c;它支持对文件系统的修改作为一次提交来一层层的叠加&#xff0c;同时可以将不同目录挂载到同一个虚拟文件系统下(unite several dir…

C练习——汉诺塔

题目&#xff1a; 汉诺塔问题是一个经典的问题。汉诺塔&#xff08;Hanoi Tower&#xff09;&#xff0c;又称河内塔&#xff0c;源于印度一个古老传说。 大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆…

大模型在游戏行业的应用分析

文章目录 一、大模型作用1&#xff09;节省美术成本2&#xff09;模仿用户肖像&#xff0c;精准投放3&#xff09;买量流程的自动化4&#xff09;缩短视频素材制作周期5&#xff09;例如新营销形式宣传&#xff08;图生图&#xff09;5&#xff09;故事设计6&#xff09;辅助代…

品牌帮助中心:提升企业客户服务水平与效率的实用指南

什么是品牌帮助中心&#xff1f;简单来理解&#xff0c;他就是一种加速问题解决效率的方式&#xff0c;是通过在官网设置文章库或者社区的形式&#xff0c;为客户提供自助服务&#xff0c;自我查找问题答案。是一种既能提升问题解决效率&#xff0c;又能提升品牌形象的方式。接…

150套简约流行国内外优秀网页模板打包 /个人主页网站html模板 /html+css网页设计源码(分享)

这里把自己收藏的最新150套简约流行国内外优秀网页模板打包分享给大家&#xff0c;如果有用请点赞收藏&#xff0c;无密源码&#xff0c;直接拿来就可以用的。它是htmlcss网页设计源码&#xff0c;html5网页静态模板。 我分了品类&#xff0c;按行业或应用场景&#xff0c;不但…

什么是设备管理系统?设备管理系统解决方案有何优势?

随着企业规模的不断扩大以及设备功能增加以及复杂性&#xff0c;对设备的管理提出新的挑战。由此各设备管理系统随即涌入市场。设备管理系统是对设备的运行情况、维修情况等进行记录并快速维修&#xff0c;达到提高设备维修效率&#xff0c;优化设备生命周期的综合性解决方案系…

Unity填坑-灯光烘焙相关

Unity填坑-灯光烘焙相关 文章目录 Unity填坑-灯光烘焙相关前言一、Light的模式二、光的效果分类三、各种Light模式与烘焙的说明1.Realtime,实时光2.baked,烘焙光3.mixed,混合 四、实时全局光五、其他说明1.动态物体的全局光照效果2.手机使用烘焙注意的点3.其他设置 前言 项目组…

Vscode中的node.js的安装与使用

前往官网下载安装包 Node.js 中文网 选择较为稳定的版本 安装全选下一步就好了&#xff0c;这里可以选择配置环境变量是否自动启动node.js 在控制台输入指令如果出现了版本号就代表成功了

SQL:一行中存在任一指标就显示出来

当想要统计的两个指标不在一张表中时&#xff0c;需要做关联。但很多情况下&#xff0c;也没有办法保证其中一张表的维度是全的&#xff0c;用left join或right join可能会导致数据丢失。所以借助full join处理。 1&#xff09;如&#xff0c;将下面的数据处理成表格中的效果&…