ESP32开发进阶:OLED屏幕显示旋转的3D模型

一、硬件接线

        我选择的是最常见的一块板子:ESP-WROOM-32,硬件接线如下:

  •         21 - SDA
  •         22 - SCL

二、Arduino端代码

        我们使用Arduino和Adafruit SSD1306库在OLED显示屏上绘制和旋转一个3D立方体。        

        首先,定义立方体顶点和边:

        `aa`, `bb`, `cc`:定义立方体的8个顶点的x, y, z坐标。
        `ff`, `gg`:定义立方体的12条边的起始和终止顶点索引。

const signed int aa[8] = {8, -8, -8, 8, 8, -8, -8, 8}; // x
const signed int bb[8] = {8, 8, -8, -8, 8, 8, -8, -8}; // y
const signed int cc[8] = {-8, -8, -8, -8, 8, 8, 8, 8}; // zconst int ff[12] = {0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3}; // start
const int gg[12] = {1, 2, 3, 0, 5, 6, 7, 4, 4, 5, 6, 7}; // end

        接着,初始化旋转角度:

        `rotx`, `roty`, `rotz`:定义绕x轴、y轴和z轴的旋转角度。

float rotx = 0.0;
float roty = 0.0;
float rotz = 0.0;

        然后,计算旋转后的立方体顶点,并在OLED屏幕上绘制,定义`Disply3D`函数:计算旋转矩阵(绕x, y, z轴的旋转矩阵),遍历每个顶点,应用旋转矩阵,更新顶点坐标。将每个顶点的3D坐标转换为2D屏幕坐标。清空显示屏并绘制立方体的12条边。

        最后,在主函数里不断循环更新立方体的旋转角度,并调用 `Disply3D` 函数进行绘制。

        完整代码如下:

#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <math.h>#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);const signed int aa[8] = {8, -8, -8, 8, 8, -8, -8, 8}; // x 
const signed int bb[8] = {8, 8, -8, -8, 8, 8, -8, -8}; // y 
const signed int cc[8] = {-8, -8, -8, -8, 8, 8, 8, 8}; // zconst int ff[12] = {0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3}; // start
const int gg[12] = {1, 2, 3, 0, 5, 6, 7, 4, 4, 5, 6, 7}; // endfloat rotx = 0.0;
float roty = 0.0;
float rotz = 0.0;void setup() {Serial.begin(9600);if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {Serial.println(F("SSD1306 allocation failed"));for(;;);}display.clearDisplay();
}void Disply3D(float xpos, float ypos, float zpos) {int newx[8];int newy[8];float sinax = sin(rotx);float cosax = cos(rotx);float sinay = sin(roty);float cosay = cos(roty);float sinaz = sin(rotz);float cosaz = cos(rotz);for (int i = 0; i < 8; i++) {float x = aa[i];float y = bb[i];float z = cc[i];float yt = y * cosax - z * sinax;float zt = y * sinax + z * cosax;y = yt;z = zt;float xt = x * cosay - z * sinay;zt = x * sinay + z * cosay;x = xt;z = zt;xt = x * cosaz - y * sinaz;yt = x * sinaz + y * cosaz;x = xt;y = yt;x = x + xpos;y = y + ypos;z = z + zpos;newx[i] = (x * 64 / z) + SCREEN_WIDTH / 2;newy[i] = (y * 64 / z) + SCREEN_HEIGHT / 2;}display.clearDisplay();for (int i = 0; i < 12; i++) {int vertex = ff[i];int sx = newx[vertex];int sy = newy[vertex];vertex = gg[i];int ex = newx[vertex];int ey = newy[vertex];display.drawLine(sx, sy, ex, ey, SSD1306_WHITE);}display.display();
}void loop() {Disply3D(0, 0, 31);rotx += 0.02;roty += 0.03;rotz += 0.01;delay(50);
}

三、实际效果

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

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

相关文章

CSS(七)——CSS 列表和CSS Table(表格)

目录 CSS 列表 列表 作为列表项标记的图像 列表 - 简写属性 移除默认设置 所有的CSS列表属性 CSS 表格 表格边框 折叠边框&#xff08;border-collapse&#xff09; 表格宽度和高度 表格文字对齐 表格填充 表格颜色 CSS 列表 CSS 列表属性作用如下&#xff1a; 设…

C#开发的全屏图片切换效果应用 - 开源研究系列文章 - 个人小作品

这天无聊&#xff0c;想到上次开发的图片显示软件《 PhotoNet看图软件 》&#xff0c;然后想到开发一个全屏图片切换效果的应用&#xff0c;类似于屏幕保护程序&#xff0c;于是就写了此博文。这个应用比较简单&#xff0c;主要是全屏切换换图片效果的问题。 1、 项目目录&…

【Vue3】watch 监视 ref 定义的数据

【Vue3】watch 监视 ref 定义的数据 背景简介开发环境开发步骤及源码参数说明 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努…

【C++进阶学习】第八弹——红黑树的原理与实现——探讨树形结构存储的最优解

二叉搜索树&#xff1a;【C进阶学习】第五弹——二叉搜索树——二叉树进阶及set和map的铺垫-CSDN博客 AVL树&#xff1a; ​​​​​​【C进阶学习】第七弹——AVL树——树形结构存储数据的经典模块-CSDN博客 前言&#xff1a; 在前面&#xff0c;我们已经学习了二叉搜索树和…

PCIe 6.0为什么需要14-bit tag

1.TLP中的tag是什么 在PCIe TLP&#xff08;Transaction Layer Packet&#xff09;中&#xff0c;tag是分配给特定Non-Posted Request的编号&#xff0c;协议要求CPL/CPLD中的tag 与对应non-post request TLP中的tag保持一致&#xff0c;因此Requester可以使用tag来识别CPL…

免费【2024】springboot 趵突泉景区的智慧导游小程序

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

十、SpringBoot 统⼀功能处理【拦截器、统一数据返回格式、统一异常处理】

十、SpringBoot 统⼀功能处理 1. 拦截器【HandlerInterceptor、WebMvcConfig】1.1 拦截器快速⼊⻔⾃定义拦截器&#xff1a;实现HandlerInterceptor接⼝&#xff0c;并重写其所有⽅法注册配置拦截器&#xff1a;实现WebMvcConfigurer接⼝&#xff0c;并重写addInterceptors⽅法…

堆(c++)

堆是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。 堆总是满足下列性质&#xff1a; 堆中某个节点的值总是不大于或不小于其父节点的值&#xff1b;堆总是一棵完全二叉树。 常见的堆有二叉堆、斐波那契堆等。 堆是非线性数据结构&#…

初识C++ · map和set的使用

目录 前言&#xff1a; 1 set 2 map 前言&#xff1a; 在前面阶段&#xff0c;我们已经学习了stl里面的部分容器&#xff0c;比如vector,list,deque等&#xff0c;这些容器都被称为序列式容器&#xff0c;也就是每个值之间式没有关联的&#xff0c;那么今天介绍的容器&…

IGV.js | 载入自己下载的gtf文件

1.安装 htslib-1.20 https://www.htslib.org/doc/tabix.html J3$ cd ~/Downloads/ $ wget https://github.com/samtools/htslib/releases/download/1.20/htslib-1.20.tar.bz2 $ tar jxvf htslib-1.20.tar.bz2编译安装&#xff1a; $ cd htslib-1.20/ $ ./configure --prefix/…

vue的三大核心知识点

响应式&#xff1a; 监听data属性getter setter(包括数组)模板编译&#xff1a; 模板到render函数再到vnodevdom&#xff1a; patch(elem, vnode)和patch(vnode, newVnode) vue组件初次渲染过程 解析模板为render函数&#xff08;或在开发环境已完成&#xff0c;vue-loader&a…

WIX Toolset 3.11 对本地化的支持方案

1.准备主题文件和本地化文件 WIX Toolset种主题文件为xml文件&#xff0c;负责配置控件的布局&#xff0c; 本地化文件为wxl文件&#xff0c;负责配置待加载的字符串&#xff0c;主题文件根据ID加载需要显示的文字内容。考虑到英文和中文字符长度大小不一&#xff0c;所以这里…

渗透测试——prime1靶场实战演练{常用工具}端口转发

文章目录 概要信息搜集 概要 靶机地址&#xff1a;https://www.vulnhub.com/entry/prime-1,358 信息搜集 nmap 扫网段存活ip及端口 找到除了网关外的ip&#xff0c;开放了80端口&#xff0c;登上去看看 是一个网站&#xff0c;直接上科技扫一扫目录 python dirsearch.py -u …

尝试带你理解 - 进程地址空间,写时拷贝

序言 在上一篇文章 进程概念以及进程状态&#xff0c;我们提到了 fork 函数&#xff0c;该函数可以帮我们创建一个子进程。在使用 fork 函数时&#xff0c;我们会发现一些奇怪的现象&#xff0c;举个栗子&#xff1a; 1 #include <stdio.h>2 #include <unistd.h>3 …

跟《经济学人》学英文:2024年07月20日这期 The Russell 2000 puts in a historic performance

Why investors have fallen in love with small American firms The Russell 2000 puts in a historic performance 罗素2000指数&#xff1a; 罗素2000指数&#xff08;英语&#xff1a;Russell 2000 Index&#xff09;为罗素3000指数中收录市值最小的2000家&#xff08;排序…

学习笔记 韩顺平 零基础30天学会Java(2024.7.25)

P425 枚举类引出 举了一个例子&#xff0c;季节类创建对象&#xff0c;但是根据Java的规则&#xff0c;可以设置春夏秋冬以外的对象&#xff0c;而且可以修改&#xff0c;这样就会不符合实际&#xff0c;因此引出枚举 P426 自定义枚举类 1.构造器私有化&#xff0c;使外面没有办…

深入解析 GPT-4o mini:强大功能与创新应用

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由 JohnKi 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f4e2;未来很长&#…

C++ 列式内存布局数据存储格式 Arrow

Apache Arrow 优点 : 高性能数据处理&#xff1a; Arrow 使用列式内存布局&#xff0c;这特别适合于数据分析和查询操作&#xff0c;因为它允许对数据进行高效批量处理&#xff0c;减少CPU缓存未命中&#xff0c;从而提升处理速度。 零拷贝数据共享&#xff1a; Arrow …

【YashanDB知识库】yasdb jdbc驱动集成druid连接池,业务(java)日志中有token IDENTIFIER start异常

问题现象 客户的java日志中有如下异常信息&#xff1a; 问题的风险及影响 对正常的业务流程无影响&#xff0c;但是影响druid的merge sql功能&#xff08;此功能会将sql语句中的字面量替换为绑定变量&#xff0c;然后将替换以后的sql视为同一个&#xff0c;然后用做执行性能统…

Vue3扁平化Tree组件的前端分页实现

大家好&#xff0c;我是小卷。得益于JuanTree的扁平化设计&#xff0c;在数据量很大的情况下除了懒加载&#xff0c;使用前端分页也是一种解决渲染性能问题的可选方案。 用法 要实现的文档&#xff1a; 分页效果&#xff1a; 实现 新增属性&#xff1a; 组件setup方法中新增…