OpenGL三维小球碰撞实现方法(glm、glfw)
小萌新刚开始学OpenGL,想做一个三维小球碰撞模拟。一开始试了好多写法,但都有问题,不断改进,终于完成了,感觉有必要记录一下。
首先,为了能够无限添加小球,我采用链表结构,并定义了小球结构体,其中包含小球的各个物理属性。
struct ball {glm::vec3 position; //球心坐标glm::vec3 speed; //速度矢量glm::vec3 color;//可有可无float r; //小球半径float m; //小球质量struct ball* next;
};
在渲染循环里面加上p->position += p->speed * deltaTime;实现小球移动。deltatime为渲染的时间间隔。
然后就是简单的循环,用来筛选发生碰撞的小球。
struct ball* p = head;
struct ball* q;while (p != NULL) { q = p->next;while ((q != NULL)) {if ((veclength(p->position - q->position) <= (p->r + q->r))) {}q = q->next;}p = p->next;}
接着最关键的就是发生碰撞的两个小球的代码了。
一开始,我尝试先在草稿纸上,把碰撞后的速度算出来。然后if他们之间的距离小于半径之和,就给他们的速度附上碰撞后的值。
然而,当我满怀期待地运行的时候,发现只有少数小球符合要求,大多数小球刚一碰撞,就直接飞走了。于是我只好回来再看代码,发现可能是因为重复判定。也就是赋值完速度之后的下一帧,他们可能还没有分离,这时候又会给速度赋值一次。
于是我添加了一个开关,当两个球分离之前,只会执行一次碰撞速度赋值。
当我运行的时候又发现,当两个球未分离的时候,如果有第三个球撞上来,那第一个球和第二个球就会发生重合。这也是不对的。
觉得这个问题过于复杂的我决定另辟蹊径。想到了一种更接近自然界本质的方法,那就是弹力。小球碰撞速度的改变,终究还是因为他们之间的相互作用力,给了他们加速度。
于是我在小球属性里面添加了加速度glm::vec3 a,并且在渲染循环里面添加了p->speed += p->a * deltaTime;当小球发生碰撞时,根据质量反比,赋给他们分离的加速度99999.0f/m。
if ((veclength(p->position - q->position) <= (p->r + q->r))) {p->a = glm::normalize(p->position - q->position) * 999999.0f / p->m;q->a = glm::normalize(q->position - p->position) * 999999.0f / q->m;}
经过不断实验,我发现虽然这样解决了上述问题,但是又出现了新的问题:
1、当两个质量较小的球,即使以很慢的速度碰撞,碰撞之后速度会变得很大。
2、当多个小球竖直叠在一起时,会发生严重的弹跳。
3、同一个小球无法同时和多个小球同时碰撞
针对上述问题我又进行了改进。
对于问题1、2,是因为当两个小球分离或者接触的瞬间,和加速度改变的瞬间有误差。这是由于小球的移动终究是离散的,不是移动的。于是我想到了把恒力改为随小球距离变化的保守力。并且当小球刚接触的时候,这个力得趋于0,并且要随距离减少快速增加(防止球质量过大时吞球)。于是我选择了指数函数,A^x^2-1.具体需要自己调试。
对于问题三,是因为一开始加速度用的是=,不能叠加,于是我改成了+=。完美(我觉得)解决了上述问题。
此外,由于自然界不存在完全弹性碰撞,因此我加了一个随速度阻尼,保证熵增。
最终代码如下:
void BALLMOVE() {struct ball* p = head;struct ball* q;while (p != NULL) { p->speed += p->a * deltaTime;p->speed += 30.0f * deltaTime * glm::vec3(0, -1, 0);//这是重力加速度p->position += p->speed * deltaTime;q = p->next;p->a = glm::vec3(0, 0, 0);while ((q != NULL)) {if ((veclength(p->position - q->position) <= (p->r + q->r))) {float k = fabs(veclength(p->position - q->position) - (p->r + q->r));float kn = pow(7,k*k)-1;p->a += kn*(glm::normalize(p->position - q->position) * 999999.0f - (p->speed - q->speed) * 100000.0f) / p->m;q->a += kn*(glm::normalize(q->position - p->position) * 999999.0f - (q->speed - p->speed)*100000.0f) / q->m; }q = q->next;}p = p->next;}}
将这个函数插入到渲染循环里面,就可以实现小球碰撞啦。
OpenGL三维小球碰撞实现方法(glm、glfw)相关推荐
- Simscape基础教程之实例(一)——使用Simscape三维物理仿真自由落体小球碰撞平面
一. 简介 本实例使用MATLAB/Simulink里面的simscape,实现自由落体小球碰撞平面的三维物理仿真,可用于新手入门simscape的参考示例. 二. 准备工作 需要安装的工具箱 (1) ...
- 三维投影总结:数学原理、投影几何、OpenGL教程、我的方法
如果要得到pose视图,除非有精密的测量方法,否则进行大量的样本采集时很耗时耗力的.可以采取一些取巧的方法,正如A Survey on Partial of 3d shapes,描述的,可以利用已得到 ...
- OpenGL三维图形编程技术(转)
人们对三维图形技术的研究已经经历了一个很长的历程,而且涌现了许多三维图形开发工具,其中SGI公司推出的GL(Graphics Library)三维图形库表现尤为突出,它易于使用且功能强大.随着计算机技 ...
- 01 C语言实现动态气泡碰撞和移动的效果,小球碰撞,Win7气泡壁纸,碰撞算法
C语言实现动态气泡碰撞和移动的效果 作者 将狼才鲸 创建日期 2023-01-29 Git源码仓库地址:C语言实现动态气泡碰撞和移动的效果 CSDN文章地址:01 C语言实现动态气泡碰撞和移动的效果 ...
- OPENGL三维场景搭建、漫游、交互
OPENGL三维场景搭建.漫游.交互 标签(空格分隔): OPENGL 这是博主的一次实验,实验截止日期还没有到.等deadline过后,博主附上源码. 源码地址:更新:OPENGL三维场景搭建.漫游 ...
- Java反弹球两球相撞_java实现小球碰撞反弹
java实现小球碰撞反弹 java实现小球碰撞反弹 首先我们要在一个窗口里面显示这个功能,因此引入JFrame类然后创建一个窗口代码如下: JFrame win=new JFrame();//新建窗口 ...
- JS实现小球碰撞边界反弹-点击消失(详细解析实现思路)
本篇文章给大家带来的是原生JS实现小球碰到边界就反弹,点击小球时小球被会销毁,并重新创建一个小球,让小球的数量一直保持在初始的数量,按照思路按步骤进行讲解,只需要源码的小伙伴可以定位到文本末尾直接复制 ...
- js 小球碰壁反弹and小球碰撞
好像好几天没有更博了呢,最近有点变懒了,这样不好,不好~~我们要做热爱学习的好孩子,嘻嘻,今天下午补上... 我们在学习js的时候,一个很经典的案例就是小球的碰壁反弹效果啦~简单的小球碰壁效果可以慢慢 ...
- 绘制canvas彩色泡泡小球碰撞
globalCompositeOperation带来的不一样的烟花 一.知识点 1.动画: setInterval( function(){ d ...
- 服务器物理碰撞检测,一种在服务器端实现三维游戏碰撞检测的方法
1.一种在服务器端实现三维游戏碰撞检测的方法,其特征在于,包括:在三维游戏场景中的物体外面预置一个包围体,所述包围体包围该物或物的主要部分,表示包围体的面的数值存储于游戏地图文件中:在游戏玩家的外面预 ...
最新文章
- Firewall防火墙应用案例
- 发展大数据还有三道坎要迈
- C/C++中程序内存区域划分大总结
- Java Formatter locale()方法与示例
- 打开运行PS、AI等软件时卡在启动窗口的解决办
- 过滤器在图纸上的符号_看不懂电气图纸?资深级老师傅教你如何识图,学会后受用一生...
- proteus三输入与非门名字_商标取名大全-有创意的2020商标名字大全
- ARTS打卡计划第一周-Tips-ControllerAdvice的使用
- vc mysql ado blob_在VC下采用ADO实现BLOB(Binary)数据的存储,读取,修改,删除。...
- android+图标自动排列,Android用RecyclerView实现图标拖拽排序以及增删管理
- j2me模拟器qq2007_如何在J2ME中创建MIDlet
- 基于单片机和C语言的毕业设计,毕业论文基于51单片机的C语言程序设计实训100例(1)(喜欢就下吧)...
- 肖忠付武汉大学计算机学院,丁立新(武汉大学计算机学院教授)_百度百科
- Base32 应用与原理解析
- 逻辑教育大厂必备IOS面试突击班
- python模糊层次分析法案例_python实现AHP算法的方法实例(层次分析法)
- 不同因子影响下的不同情境的世界气温预测(的辣鸡tkinter UI可视化DEMO)
- Android实现通过浏览器点击链接打开本地应用(APP)
- CEF 最新版本自己编译加上支持播放MP4视频
- Python学习笔记(八)爬虫基础(正则和编解码)