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

news2025/2/28 16:12:47

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绘制三维坐标系(动态曲线显示) ↩︎

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

更换为mainwindow.ui更新工程架构

文章目录 前言一、新建带mainwindow.ui的工程1.新建工程2. 添加工程模块添加opencv的库3.添加资源3.1工程上添加资源3.2引用资源 4.添加曲线文件4.1 复制关键文件到新工程4.2 新进显示曲线的ui带.h的为了方面名字取一样4.3添加曲线显示控件4.4 添加工具 5. 添加曲线.h文件内容6…

大数据深度学习ResNet深度残差网络详解:网络结构解读与PyTorch实现教程

文章目录 大数据深度学习ResNet深度残差网络详解&#xff1a;网络结构解读与PyTorch实现教程一、深度残差网络&#xff08;Deep Residual Networks&#xff09;简介深度学习与网络深度的挑战残差学习的提出为什么ResNet有效&#xff1f; 二、深度学习与梯度消失问题梯度消失问题…

Apache-Common-Pool2中对象池的使用方式

最近在工作中&#xff0c;对几个产品的技术落地进行梳理。这个过程中发现一些朋友对如何使用Apache的对象池存在一些误解。所以在写作“业务抽象”专题的空闲时间里&#xff0c;本人觉得有必要做一个关于对象池的知识点和坑点讲解。Apache Common-Pool2 组件最重要的功能&#…

nvm安装高版本Nodejs报错

文章概叙 之前使用1.1.17版本的nvm&#xff0c;切换使用18的Nodejs的时候报错&#xff0c;经过短暂的思考&#xff0c;决定使用1.1.12的nvm的无聊故事。 吐槽 今天的故事比较无奈&#xff0c;由于某些原因&#xff0c;现在需要做rn的开发&#xff0c;至于为啥不是flutter&am…

《工具录》dig

工具录 1&#xff1a;dig2&#xff1a;选项介绍3&#xff1a;示例4&#xff1a;其他 本文以 kali-linux-2023.2-vmware-amd64 为例。 1&#xff1a;dig dig 是域名系统&#xff08;DNS&#xff09;查询工具&#xff0c;常用于域名解析和网络故障排除。比 nslookup 有更强大的功…

一张图总结架构设计的40个黄金法则

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;很多小伙伴拿到非常优质的架构机会&#xff0c;常常找尼恩求助&#xff1a; 尼恩&#xff0c;我这边有一个部门技术负责人资深架构师的机会&#xff0c;非常难得&#xff0c; 但是有一个大厂高P在抢&#xff0…

为什么很多公司选择不升级JDK版本,仍然使用JDK8?

在讨论为什么许多公司选择不升级JDK版本&#xff0c;而继续使用JDK 8时&#xff0c;我们需要从多个角度来分析这个问题。以下是根据您提供的背景信息进行的一些分析和真实案例。 本文已收录于&#xff0c;我的技术网站 ddkk.com&#xff0c;有大厂完整面经&#xff0c;工作技术…

H5网站封装成App的高效转换之旅

在移动互联网时代&#xff0c;App&#xff08;应用程序&#xff09;和H5&#xff08;HTML5网站&#xff09;是两种常见的移动解决方案。App通常提供更流畅的用户体验和更丰富的功能&#xff0c;而H5网站则以其开发成本低、更新快捷和无需安装等优势受到青睐。尽管如此&#xff…

【java八股文】之Spring系列篇

1、你怎么理解Spring&#xff1f; Spring是个轻量级的框架&#xff0c;简化了应用的开发程序&#xff0c;提高开发人员的系统维护性&#xff0c;不过配置消息比较繁琐&#xff0c;所以后面才出选了SpringBoot的框架。 Spring的核心组件 &#xff1a; Spring Core 、 Spring Con…

Video接口介绍

屏库 https://m.panelook.cn/index_cn.php Open LDI, open lvds display interface OpenLDI and LVDS是兼容的&#xff0c; 是一种电平 https://www.ti2k.com/178597.html MIPI DSI/Camera crosLink FPD-LINK(Flat panel display link)是National(TI) LVDS技术&#xff0c; …

Openstack云计算(六)Openstack环境对接ceph

一、实施步骤&#xff1a; &#xff08;1&#xff09;客户端也要有cent用户&#xff1a; useradd cent && echo "123" | passwd --stdin cent echo -e Defaults:cent !requiretty\ncent ALL (root) NOPASSWD:ALL | tee /etc/sudoers.d/ceph chmod 440 /et…

[足式机器人]Part2 Dr. CAN学习笔记-Advanced控制理论 Ch04-12+13 不变性原理+非线性系统稳定设计

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-Advanced控制理论 Ch04-1213 不变性原理非线性系统稳定设计 1. Invariance Princilpe-LaSalle;s Theorem不变性原理2. Nonlinear Basic Feedback Stabilization 非线性系统稳定设计 1. Invarianc…

Java内存模型之重排序

文章目录 1.什么是重排序2.重排序的好处3.重排序的三种情况4.用volatile修正重排序问题 1.什么是重排序 首先来看一个代码案例&#xff0c;尝试分析一下 x 和 y 的运行结果。 import java.util.concurrent.CountDownLatch;/*** 演示重排序的现象&#xff0c;直到达到某个条件…

css深度选择器 /deep/

一、/deep/的含义和使用 /deep/ 是一种 CSS 深度选择器&#xff0c;也被称为深度组合器或者阴影穿透组合器&#xff0c;主要用在 Web 组件样式封装中。 在 Vue.js 或者 Angular 中&#xff0c;使用了样式封装技术使得组件的样式不会影响到全局&#xff0c;也就是说组件内部的…

java数据结构与算法:单链表 SinglyLinkedList

单链表 SinglyLinkedList 创建实现类并实现方法 package com.lhs;public class SinglyLinkedList<E> implements List<E>{// 头节点private Node<E> first;// 尾节点private Node<E> last;// 节点数量private int size;public static class Node<…

PDCA/绩效管理活动

现代绩效管理理论认为&#xff0c;绩效管理活动是一个连续的过程&#xff0c;是指管理者用来确保自己下属员工的工作行为和工作产出与组织的目标保持一致的手段及过程。人们通常用一个循环过程来描述绩效管理的整个过程。我们认为&#xff0c;一个组织的员工绩效管理活动由四个…

Dockerfile的ADD和COPY

文章目录 环境ADD规则校验远程文件checksum添加Git仓库添加私有Git仓库ADD --link COPYCOPY --parent 使用ADD还是COPY&#xff1f;参考 环境 RHEL 9.3Docker Community 24.0.7 ADD ADD 指令把 <src> 的文件、目录、或URL链接的文件复制到 <dest> 。 ADD 有两种…

element表格数据,表头上(下)角标,html字符串渲染

1. 问题描述 在动态渲染的element表格中&#xff0c;表头和表中数据是一个含有html的字符串&#xff0c;需要渲染 2. 效果 3. 代码 const columns ref([{ text: 差值<sub>-3</sub> / 10<sup>-6</sup>℃<sup>-1</sup>, value: aallowEr…

Android平台RTMP推送|轻量级RTSP服务|GB28181设备接入模块之实时快照保存JPG还是PNG?

JPG还是PNG&#xff1f; JPG和PNG是两种常见的图片文件格式&#xff0c;在压缩方式、图像质量、透明效果和可编辑性等方面存在显著差异。 压缩方式&#xff1a;JPG是一种有损压缩格式&#xff0c;通过丢弃图像数据来减小文件大小&#xff0c;因此可能会损失一些图像细节和质量…