Qt/C++基于重力模拟的像素点水平堆叠效果

本文将深入解析一个基于 Qt/C++ 的像素点模拟程序。程序通过 重力作用,将随机分布的像素点下落并水平堆叠,同时支持窗口动态拉伸后重新计算像素点分布。


程序功能概述

  • 随机生成像素点:程序在初始化时随机生成一定数量的像素点,每个像素点有随机的初始位置和速度。
  • 重力模拟:像素点在重力作用下不断下落,并与地面发生弹性碰撞。
  • 水平堆叠:像素点在下落后静止并水平堆叠,模拟堆积效果。
  • 碰撞检测:像素点之间检测是否发生碰撞并进行弹性处理。
  • 窗口自适应:当窗口大小变化时,自动重新分布像素点。

核心实现细节

1. 像素点结构体

像素点通过 Pixel 结构体定义,包含以下属性:

  • xy:像素点的二维位置。
  • vxvy:像素点的水平和垂直速度。
  • isStatic:标记像素点是否已经静止。

定义如下:

struct Pixel {double x, y;       // 像素点位置double vx, vy;     // 像素点速度bool isStatic;     // 是否已经静止
};

2. 重力与碰撞模拟

重力计算

每个像素点的垂直速度受重力影响,逐帧增加重力值:

p.vy += gravity;

像素点的速度更新后,其位置随之更新:

p.x += p.vx;
p.y += p.vy;
边界检测

为了防止像素点越过窗口边界,加入边界检测与反弹逻辑:

if (p.x < radius || p.x > width() - radius) {p.vx *= -restitution; // 水平方向的反弹p.x = clamp(p.x, (double)radius, (double)(width() - radius));
}

在这里:

  • radius 是像素点的半径,防止越界。
  • restitution 控制反弹的弹性,值为 0-11 表示完全弹性,0 表示无弹性。
碰撞地面

当像素点接触地面时,垂直速度反弹,同时逐渐水平减速:

if (p.y > groundLevel) {p.vy *= -restitution; // 垂直方向反弹p.y = groundLevel;    // 防止越过地面p.vx *= damping;p.vy *= damping;
}
  • groundLevel 表示地面高度。
  • damping 表示速度阻尼系数,用于减小速度,模拟摩擦力。

3. 静止与堆叠机制

像素点在速度足够小的情况下会被标记为静止:

if (std::abs(p.vx) < staticThreshold && std::abs(p.vy) < staticThreshold) {p.vx = 0;p.vy = 0;p.isStatic = true;
}

静止后,像素点不再更新速度和位置,从而节省计算资源。

水平堆叠的网格机制

为了实现堆叠效果,使用了一个二维网格 grid 来记录像素点的静止位置:

std::vector<std::vector<bool>> grid(gridWidth, std::vector<bool>(gridHeight, false));

每个网格单元表示一个像素点的静止状态。当像素点静止后,更新对应的网格状态:

int gridX = p.x / (2 * radius);
int gridY = groundLevel / (2 * radius);
if (gridX >= 0 && gridX < gridWidth && gridY >= 0 && gridY < gridHeight) {grid[gridX][gridY] = true;
}

通过检测 grid 的状态,确保新下落的像素点不会与静止点重叠。


4. 碰撞处理

当两个像素点之间的距离小于其直径时,认为发生了碰撞。处理逻辑如下:

double distance = std::sqrt(dx * dx + dy * dy);
if (distance < 2 * radius && distance > 1e-6) { // 避免除以零double overlap = 2 * radius - distance;double nx = dx / distance;double ny = dy / distance;p.x += nx * overlap / 2;p.y += ny * overlap / 2;other.x -= nx * overlap / 2;other.y -= ny * overlap / 2;// 水平速度调整p.vx *= damping;other.vx *= damping;
}

这里:

  • overlap 表示像素点之间的重叠距离。
  • nxny 是碰撞方向的单位向量。
  • 调整每个像素点的位置以消除重叠,并减小速度。

5. 窗口自适应

窗口大小改变事件

当窗口大小改变时,重新初始化像素点,以适应新的窗口尺寸。通过重载 resizeEvent 实现:

void GravityWidget::resizeEvent(QResizeEvent *event) {initializePixels(); // 重新初始化像素点QWidget::resizeEvent(event);
}
像素点重新初始化

重新生成随机分布的像素点:

void GravityWidget::initializePixels() {pixels.clear();for (int i = 0; i < 200; ++i) {Pixel p;p.x = std::rand() % width();p.y = std::rand() % height();p.vx = 0;p.vy = 0;p.isStatic = false;pixels.push_back(p);}
}

6. 图形绘制

通过重载 paintEvent 实现像素点的绘制:

void GravityWidget::paintEvent(QPaintEvent *) {QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);painter.setBrush(Qt::blue);for (const auto &p : pixels) {painter.drawEllipse(QPointF(p.x, p.y), 3, 3); // 绘制小圆点}
}

运行效果

  1. 重力下落:随机生成的像素点在重力作用下逐渐下落。
  2. 弹性碰撞:像素点彼此碰撞时会弹开,最终逐渐稳定。
  3. 水平堆叠:像素点在地面静止后自然堆叠,形成类似水波的排列效果。
  4. 窗口自适应:拉伸或缩小窗口时,像素点会重新生成并分布。

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

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

相关文章

矩阵重构——sortrows函数

s o r t r o w s sortrows sortrows函数依据某列的属性对其元素所在的行进行排序从而进行矩阵的排序 s o r t r o w s sortrows sortrows函数常用方法&#xff1a; 1. 1. 1. s o r t r o w s ( a , [ c 1 , c 2 ] ) sortrows(a,[c_1,c_2]) sortrows(a,[c1​,c2​])&#xff0c…

Linux之网络基础

网络发展 网络的发展可以从人与人之间的工作模式开始谈起, 人与人的工作模式反应了机器与机器的工作模式: 1. 独立模式: 在网络发展的早期计算机间处于独立模式, 计算机之间相互独立 最开始计算机之间是独立运行的, 数据之间的交互需要人用软盘等存储介质拷贝过去, 一般涉及…

【pyspark学习从入门到精通22】机器学习库_5

训练-验证分割 TrainValidationSplit 模型为了选择最佳模型&#xff0c;会对输入数据集&#xff08;训练数据集&#xff09;进行随机分割&#xff0c;分成两个子集&#xff1a;较小的训练子集和验证子集。分割只执行一次。 在这个例子中&#xff0c;我们还将使用 ChiSqSelect…

【Petri网导论学习笔记】Petri网导论入门学习(十一) —— 3.3 变迁发生序列与Petri网语言

目录 3.3 变迁发生序列与Petri网语言定义 3.4定义 3.5定义 3.6定理 3.5例 3.9定义 3.7例 3.10定理 3.6定理 3.7 有界Petri网泵引理推论 3.5定义 3.9定理 3.8定义 3.10定义 3.11定义 3.12定理 3.93.3 变迁发生序列与Petri网语言 对于 Petri 网进行分析的另一种方法是考察网系统…

IDEA:配置Serializable class without ‘serialVersionUID’ 找不到

在使用Java原生序列化的时候&#xff0c;serialVersionUID起到了一个类似版本号的作用&#xff0c;在反序列化的时候判断serialVersionUID如果不相同&#xff0c;会抛出InvalidClassException。 File -> Settings -> Editor -> Inspections -> 搜索 Serialization …

win10 禁止更新

一、winR 输入 regedit 二、输入注册列表路径&#xff1a; &#xff08;1&#xff09;计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings &#xff08;2&#xff09;按照格式&#xff0c;创建文件命名: FlightSettingsMaxPauseDays &#xff08;3&…

OpenAI Whisper 语音识别 模型部署及接口封装

环境配置: 一、安装依赖&#xff1a; pip install -U openai-whisper 或者&#xff0c;以下命令会从这个存储库拉取并安装最新的提交&#xff0c;以及其Python依赖项&#xff1a; pip install githttps://github.com/openai/whisper.git 二、安装ffmpeg&#xff1a; cd …

springboot视频网站系统的设计与实现(代码+数据库+LW)

摘 要 使用旧方法对视频信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在视频信息的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题。 这次开发的视频网站系统管理员功…

安装QT6.8(MSVC MinGW)+QT webengine+QT5.15.2

本篇主要针对只使用过QT5的qmake&#xff0c;没有用过MSVC&#xff0c;VS的老同学。 建议一部分一部分安装&#xff0c;全部勾选安装遇到问题会中断&#xff0c;前功尽弃。 我自己需要的是QT5&#xff0c;编出的软件用在公司设备上。 QT6&#xff1a;建议也安装学习&#xf…

自动驾驶目标检测融合全貌

1、early fusion 早期融合&#xff0c;特点用到几何空间转换3d到2d或者2d到3d的转换&#xff0c;用像素找点云或者用点云找像素。 2、deep fusion 深度融合&#xff0c;也是特征级别融合&#xff0c;也叫多模态融合&#xff0c;如bevfusion范式 3、late fusion 晚融合&#x…

Microsoft Excel如何插入多行

1.打开要编辑的excel表&#xff0c;在指定位置&#xff0c;鼠标右键点击“插入”一行 2.按住shift键&#xff0c;鼠标的光标箭头会变化成如下图所示 3.一直按住shift键和鼠标左键&#xff0c;往下拖动&#xff0c;直至到插入足够的行

node.js基础学习-http模块-创建HTTP服务器、客户端(一)

http模块式Node.js内置的模块&#xff0c;用于创建和管理HTTP服务器。Node.js使用JavaScript实现&#xff0c;因此性能更好。 使用http模块创建服务器&#xff0c;我们建议使用commonjs模块规范&#xff0c;因为很多第三方的组件都使用了这种规范。当然es6写法也支持。 下面就是…

2024御网杯信息安全大赛个人赛wp(misc方向)

目录 一.信息安全大赛的通知二、编码转换1. 第一部分2. 第二部分3. 第三部分 三、1.txt四、buletooth 题目附件以及工具链接&#xff1a; 通过网盘分享的文件&#xff1a;御网杯附件 链接: https://pan.baidu.com/s/1LNA6Xz6eZodSV0Io9jGSZg 提取码: jay1 –来自百度网盘超级会…

浅谈pdfbox2.0和pdfbox3.0的运用与区别

前言 Apache PDFBox 是一个开源的Java库&#xff0c;可以用来对PDF文档做一些基本操作&#xff0c;比如实际应用中的pdf读取、写入、合并、拆分、写文字、写图片、加水印等&#xff0c;甚至还应用到了电子签章。本文逐个介绍对pdf的操作&#xff0c;以备作为后续参考使用。 一…

《解锁计算机专业宝藏:核心编程语言与学习资料全解析》

在当今数字化浪潮汹涌澎湃、技术迭代日新月异的时代&#xff0c;计算机专业宛如一座蕴藏无尽宝藏与无限机遇的神秘殿堂&#x1f3f0;。对于莘莘学子而言&#xff0c;精准掌握核心编程语言&#xff0c;并手握优质学习资料&#xff0c;恰似寻得开启这扇殿堂大门的秘钥&#xff0c…

【计算机网络】多路转接之epoll

epoll也是一种linux中的多路转接方案(epoll也是只负责IO过程中的"等") 一、epoll相关接口的使用 1.epoll_create int epoll_create(int size); ​功能&#xff1a;创建一个epoll模型 ① int size&#xff1a;没意义了 >0就行 返回值&#xff1a;返回一个文件…

「Mac畅玩鸿蒙与硬件33」UI互动应用篇10 - 数字猜谜游戏

本篇将带你实现一个简单的数字猜谜游戏。用户输入一个数字&#xff0c;应用会判断是否接近目标数字&#xff0c;并提供提示“高一点”或“低一点”&#xff0c;直到用户猜中目标数字。这个小游戏结合状态管理和用户交互&#xff0c;是一个入门级的互动应用示例。 关键词 UI互…

Brain.js 用于浏览器的 GPU 加速神经网络

Brain.js 是一个强大的 JavaScript 库&#xff0c;它允许开发者在浏览器和 Node.js 环境中构建和训练神经网络 。这个库的目的是简化机器学习模型的集成过程&#xff0c;使得即使是没有深厚机器学习背景的开发者也能快速上手 。 概述 Brain.js 提供了易于使用的 API&#xff…

365天深度学习训练营-第P6周:VGG-16算法-Pytorch实现人脸识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 文为「365天深度学习训练营」内部文章 参考本文所写记录性文章&#xff0c;请在文章开头带上「&#x1f449;声明」 &#x1f37a;要求&#xff1a; 保存训练过…

预处理指令

1.预定义符号 预定义符号是在预处理阶段处理的。 1.__FILE__ // 进⾏编译的源⽂件 2.__LINE__ // ⽂件当前的⾏号 3.__DATE__ // ⽂件被编译的⽇期 4.__TIME__ // ⽂件被编译的时间 5.__STDC__ // 如果编译器遵循 ANSI C &#xff0c;其值为 1 &#xff0c;否则未定义…