OpenGL绘制球体模拟自由落体运动(基于Qt)
自由落体的物理公式想必大家都清楚(y=vt+0.5gt^2)。
但是用程序如何模拟这个过程呢?
1、其中比较关键的是设定一个计时器,在一个视觉暂留时间段(dt=0.02s)内根据小球的位置坐标绘制小球。
2、在小球弹到地面的时候会因为碰撞而有能量损耗,其表现形式为速度减小并反向,而速度减小则可以通过改变加速度a的大小来控制(F=ma嘛,不知道这样解释合不合理,迷)
3、终止条件的判断:
if(ball.vy<1 && ball.y<-2.0){ //中止条件
ball.vy=0;
ball.y=-2.0;
G=0;
}
这里ball.vy为速度大小,ball.y为高度坐标(地面位置为-2.0),条件为什么不是ball.vy<0呢?这是因为速度的减少或增加是以dt为单位的(非连续),不一定能取到0值,如果条件设为0那么小球会一直在一个很小的范围内震动。(不信你可以试试)
下面附上我的程序实现:(因为考试复习原因没有给小球添加纹理,后面有时间了再补上)
widget.h
QTimer *timer; //定时器
//GLuint texName; //材质路径
GLdouble dt; //间隔时间
bool direction; //小球运动方向,向下为true
double G;
GLuint *tex0;//纹理
QString bmpfile;
QPoint m_last;
double dist,horizontal,vertical;
typedef struct b //定义储存球体的结构
{
GLdouble y;
GLdouble vy;
} Ball;
Ball ball;
public slots:
void updataScene();
widget.cpp
Widget::Widget(QWidget *parent)
: QGLWidget(parent)
{
timer = new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(updataScene()));
timer->start(10);
}
void Widget::initializeGL(){
dt=0.02;
ball.y = 10 ; //初始化球体属性
ball.vy = 0 ;
direction = true;
G = 9.8;
bmpfile = "://floor.jpg";
tex0 = new GLuint;
dist = 2.0;
vertical=45.0;
horizontal=45.0;
glClearColor(0.0,0.0,0.0,0.0);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
//glEnable(GL_LIGHTING); //开启光照
// glEnable(GL_LIGHT0); //开启光源0
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glMaterialf(GL_FRONT,GL_SHININESS,64.0);
loadTexture(bmpfile,tex0);
}
void Widget::paintGL(){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glClearColor(0.6,0.6,0.6,1);
glLoadIdentity();
float eyex=dist*cos(vertical/180.0*PI)*sin(horizontal/180.0*PI);
float eyey=dist*sin(vertical/180.0*PI);
float eyez=dist*cos(vertical/180.0*PI)*cos(horizontal/180.0*PI);
gluLookAt(eyex, eyey,eyez, 0.0, 0.0, 0.0, 0, 1, 0);
//gluLookAt(1,2,1,0,0,0,0,1,0);
glDisable(GL_TEXTURE_2D); //画小球时先不使用纹理
glPushMatrix();
glTranslated(0,ball.y,0.0);
glutWireSphere(2,50,50);
if(ball.vy<1 && ball.y<-2.0){ //中止条件
ball.vy=0;
ball.y=-2.0;
G=0;
}
if(direction){ //向下运动
G=9.8;
if(ball.y-(ball.vy*dt+0.5*G*dt*dt) <=-2){
direction = false; //触发转向条件,改变direction的值,使球体运动方向改变
G += 6.0;
}
ball.y = ball.y-(ball.vy*dt+0.5*G*dt*dt); //根据牛顿运动定律计算出球的位移公式
ball.vy = ball.vy + G*dt; //根据牛顿运动定律计算出球体的速度
}
else{ //向上运动
if(ball.y >-2 && ball.vy<0){
direction = true;
}
ball.y = ball.y+(ball.vy*dt-0.5*G*dt*dt);
ball.vy = ball.vy-G*dt;
}
glPopMatrix(); //将当前矩阵弹出
glPushMatrix();
// glPushAttrib(GL_ALL_ATTRIB_BITS);
// glColor3f(0.0, 0.0, 1.0);
glEnable(GL_TEXTURE_2D);
// loadTexture(bmpfile,tex0);
glBegin(GL_QUADS);
glTexCoord2f( 0.0, 0.0 );glVertex3f(10.0,-4.0,0.0);
glTexCoord2f( 1.0, 0.0 );glVertex3f(0.0,-4.0,-6.0);
glTexCoord2f( 1.0, 1.0 );glVertex3f(-6.0,-4.0,0.0);
glTexCoord2f( 0.0, 1.0 );glVertex3f(0.0, -4.0,10.0);
glEnd();
//glPopAttrib();
glPopMatrix();
glFlush();
}
void Widget::loadTexture(QString filepath, GLuint *texture){ //加载纹理
QImage tex, buf;
if(!buf.load(filepath))
{
qDebug()<<"Error: failed to load image!";
exit(1);
}
tex = convertToGLFormat(buf); //转化为rgba类型的数据集
glGenTextures(1, texture);
glBindTexture(GL_TEXTURE_2D, *texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, tex.width(), tex.height(), GL_RGBA, GL_UNSIGNED_BYTE,tex.bits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,3);
}
void Widget::mousePressEvent(QMouseEvent *e)
{
m_last = e->pos();
}
void Widget::mouseMoveEvent(QMouseEvent *e)
{
if(e->buttons() & Qt::LeftButton)
{
QPoint m_now = e->pos();
float disx = m_now.x() - m_last.x();//两个鼠标x坐标的差
float disy = m_now.y() - m_last.y(); //m_last是之前点击事件取得的鼠标位置
//更改观察方向
horizontal -= disx/25;
vertical += disy/25;
m_last = m_now;
updateGL();
}
}
运行结果截图:
此处只截取从一定高度落下并来回弹跳的最终结果。以下为完整工程代码的链接:
https://download.csdn.net/download/did_you/10406118
OpenGL绘制球体模拟自由落体运动(基于Qt)相关推荐
- 模拟自由落体运动的小球
基于VS2019 EasyX插件 C/C++ 生成一个模拟自由落体运动的小球 #include <iostream> #include <graphics.h> #in ...
- Android模拟自由落体运动
最近想看看android的游戏开发,因此首先绘图方面得练练,突然就想到模拟一下自由落体运动.本例采用serfaceView实现,接下来上代码: 一.首先定义一个自定义控件 public class M ...
- 自由落体java编程_java模拟自由落体运动源代码
简单做了一个 import java.awt.borderlayout; import java.awt.button; import java.awt.color; import java.awt. ...
- python自由落体_VPython - example - 模拟自由落体运动
作者:liuyuan_jq 2011-04-10 from visual import * scene.width = 400 scene.height = 300 scene.autoscale = ...
- 手把手教你用Python来模拟绘制自由落体运动过程中的抛物线(附源码)
前言 前几天有个叫[-berry]的粉丝在问了一道关于自由落体运动过程中产生的抛物线作图的问题,如下图所示. 当某个物体以初速度v水平抛出,其轨迹为一条抛物线,模拟绘制这条抛物线.用高中物理知识,我们 ...
- matlab 地形模拟程序,MATLAB模拟小球自由落体运动
大部分朋友学习MATLAB,需要一个学习示例用来参考,有一个比较经典的题目就是如何利用Matlab模拟小球自由落体运动,这可能会是你的某次课后作业,这个程序的编写过程可以分为三个步骤: 第一部分,设置 ...
- lammps案例:分子自由落体运动模拟
大家好,我是小马老师. 本文分享一个比较有意思的lammps案例:分子的自由落体运动. lammps提供了fix gravity命令可设置分子或者原子的加速度. 语法规则为: fix ID group ...
- canvas动画:自由落体运动
经过前面的文章,我们已经能够在canvas画布上画出各种炫酷的图形和画面,但是这些画面都是禁止的,怎么样才能让他们动起来呢? 如何绘制基本图形可以参考:canvas基本图形绘制 如何对基本图形移动旋转 ...
- matlab小球水平抛出,如何用Matlab制作小球自由落体运动的动画
第一堂课布置了一个Mission Impossible作业,要求学生们用Matlab制作一个动画,模拟小球的自由落体运动. 以下将整个任务的问题解决的过程分享如下: 步骤一,这是一个动画的制作过程,以 ...
最新文章
- 什么才是真正赚钱?| 每日趣闻
- Object.defineProperty()方法的用法详解
- L2-001 紧急救援-团体程序设计天梯赛GPLT
- POJ 2115 C Looooops(扩展欧几里得)
- wamp修改端口localhost
- Mac磁盘如何分区?Mac系统磁盘自由分区教程!
- 系统升级时,数据库脚本执行注意事项,血的教训
- 花式打印菱形图案!!
- 三国皇帝的寡妇秘史(1)
- Skip List(跳表)
- 遥感图像-Deep Feature Alignment Neural Networks for Domain Adaptation of Hyperspectral Data高光谱数据深度特征对齐神经
- 网络优化(三)——参数初始化
- 浅谈Spring IOC的理解
- Quartz定时调度
- 【python 求100以内的偶数和和奇数和】
- c语言系统编程六:Linux进程间通信之无名管道
- Systemd工作原理及使用
- 十岁孩子幽门螺旋杆菌会不会影响发育?最好的治疗方法是这样的
- 互动协作白板与音视频实时同步技术实践
- 代码加密软件VMProtect 全新v3.6震撼上线,强势助力软件加密
热门文章
- hdu1232 畅通工程 (并查集)(浙师大OJ1307)
- A Game of Thrones(34)
- 计算机操作系统的阶段分为几个阶段,浅谈操作系统的发展历程
- 思考(八十五):IM 服务设计思路
- python网球比赛模拟主持稿_模拟讲课大赛主持人稿
- java语言程序设计教程课后题答案魏永红_《Java语言程序设计教程》习题参考答案...
- fixture ‘xxx‘ not found
- 两组字符串去重/两个列表去重
- matlab读取jra55数据,[转载][原创]灰色关联分析及Matlab程序实现
- VMware上安装CentOS系统