【OpenGL】8字循环体算法
今天在NEHE粒子效果的基础上写了一个8字循环体,果然算法什么的真是太恶心了。
关于粒子效果我就不多说了,大家可以参照NEHE的教程,写得很详细,只要有心,肯定能学会。链接如下:
http://www.owlei.com/DancingWind/
所谓的8字循环体,就是蜜蜂跳的那种8字舞蹈,上下两个圆圈绕着转。
因此,要实现8字循环体,首先得要实现如何画圆圈。
其实很简单,我们先在文件顶头定义一些所需的变量。
//圆圈的角度 float degree; //圆周率 float pi = 3.14159; //圆的半径 int r = 5; //上下圆圈的判断符 bool flg = true ; |
然后在绘制图像的那个方法里面,找到如果粒子生命<0的这段逻辑,在这段逻辑里面,如果粒子生命<0,那么就将粒子满血复活,并赋予新的坐标。我们要改的就是给新生粒子赋予新坐标的这段代码。
因为是画圆圈,已知角度、半径的情况下,就可以算出圆圈上某点的坐标,代码如下:
particle[loop].x= sin (degree*pi/180)*r; particle[loop].y= cos (degree*pi/180)*r+ (flg?5.0:-5.0); |
这里需要注意的是,sin和cos这两个方法所用的参数应该是弧度。所以我们还得先将角度算成弧度,公式如下:
弧度 = 角度*PI/180
而算y轴坐标的后面那段代码:
(flg?5.0:-5.0)
的作用是区分该圆是上圆还是下圆。
通过以上代码,可以算是圆的坐标,那么接下来我们要写一段逻辑,来算圆的轨迹。轨迹的示意图如下表示:
从以上示意图,我们可以得到以下逻辑:
//步奏一 if(degree >0 && degree <180 && flg==true) { flg = true; } //步奏二 else if(degree ==180 && flg == true) { flg = false; degree = 360; } //步奏三 else if(degree ==0 && flg == false) { flg = true; degree = 181; } //步奏四 else if(degree >=360 && flg == true) { degree = 0; } //根据上下圆,相应的递增或递减 if(flg) { degree += 1; } else { degree -= 1; }
最后画面画出来的结果是:
以下是绘图部分的所有代码,是NEHE教程的基础上略有增减,希望能对你有帮助。
int DrawGLScene(GLvoid) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); for (loop=0;loop<MAX_PARTICLES;loop++) { if (particle[loop].active) { float x=particle[loop].x; float y=particle[loop].y ; float z=particle[loop].z+zoom; glColor4f(particle[loop].r,particle[loop].g,particle[loop].b,particle[loop].life); glBegin(GL_TRIANGLE_STRIP); glTexCoord2d(1,1); glVertex3f(x+0.5f,y+0.5f,z); glTexCoord2d(0,1); glVertex3f(x-0.5f,y+0.5f,z); glTexCoord2d(1,0); glVertex3f(x+0.5f,y-0.5f,z); glTexCoord2d(0,0); glVertex3f(x-0.5f,y-0.5f,z); glEnd(); particle[loop].x+=particle[loop].xi/(slowdown*1000); particle[loop].y+=particle[loop].yi/(slowdown*1000); particle[loop].z+=particle[loop].zi/(slowdown*1000); particle[loop].xi+=particle[loop].xg; particle[loop].yi+=particle[loop].yg; particle[loop].zi+=particle[loop].zg; particle[loop].life-=particle[loop].fade; if (particle[loop].life<0.0f) { particle[loop].life=1.0f; particle[loop].fade= float ( rand ()%100)/1000.0f+0.003f; particle[loop].x= sin (degree*pi/180)*r; particle[loop].y= cos (degree*pi/180)*r+ (flg?5.0:-5.0); particle[loop].z=0.0f; particle[loop].xi=xspeed+ float (( rand ()%64)-32.0f); particle[loop].yi=yspeed+ float (( rand ()%64)-30.0f); particle[loop].zi= float (( rand ()%60)-30.0f); int colIndex = rand ()%12; particle[loop].r = color[colIndex][0]; particle[loop].g = color[colIndex][1]; particle[loop].b = color[colIndex][2]; } } } if (degree >0 && degree <180 && flg== true ) { flg = true ; } else if (degree ==180 && flg == true ) { flg = false ; degree = 360; } else if (degree ==0 && flg == false ) { flg = true ; degree = 181; } else if (degree >=360 && flg == true ) { degree = 0; } if (flg) { degree += 1; } else { degree -= 1; } return TRUE; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?