您的位置:首页 > 编程语言 > C语言/C++

C++ 实现太阳系行星系统

2016-06-25 21:03 411 查看
整个天体系统中,他们都是一颗星球(Star),区别行星和恒星只需要通过它们是否具有父节点即可;其次,对于不同的星球而言,它们通常具有自身的材质,并且不同的材质会表现出自身是否发光,由此我们有了初步的对象模型。故我们将星球分为:普通能够自转并绕某个点公转的星球(Star),具有特殊材质的星球(Planet), 能够发光的星球(LightPlanet)。一、编程模型假设:星球的运行轨道为圆形;自转速度保持相同;每次刷新绘制的时候假设时间经过了一天。二、整体思路:初始化星球对象;初始化 OpenGL 引擎, 实现 onDraw 和 onUpdate;星球应该自己负责处理自己的属性、绕行关系、变换相关绘制,因此在设计星球的类时应该提供一个绘制 draw() 方法;星球也应该自己处理自己自转公转等更新显示的绘制,因此在设计星球类时候也应该提供一个更新方法 update();在 onDraw() 中应调 用星球的 draw() 方法;在 onUpdate() 中调用星球的 update() 方法;在 onKeyboard() 键盘调整整个太阳系的显示.三、每个星球而言,都具有如下的属性:颜色 color公转半径 radius自转速度 selfSpeed公转速度 speed距离太阳中心的距离 distance绕行的星球 parentStar当前的自转的角度 alphaSelf当前的公转角度 alpha因此有如下的类:class Star {public:// 星球的运行半径GLfloat radius;// 星球的公转、自传速度GLfloat speed, selfSpeed;// 星球的中心与父节点星球中心的距离GLfloat distance;// 星球的颜色GLfloat rgbaColor[4];// 父节点星球Star* parentStar;// 构造函数,构造一颗星球时必须提供// 旋转半径、旋转速度、自转速度、绕行(父节点)星球Star(GLfloat radius, GLfloat distance,GLfloat speed, GLfloat selfSpeed,Star* parent);// 对一般的星球的移动、旋转等活动进行绘制void drawStar();// 提供默认实现,负责调用 drawStar()virtual void draw() { drawStar(); }// 参数为每次刷新画面时的时间跨度virtual void update(long timeSpan);protected:Float alphaSelf, alpha;};class Planet : public Star {public:// 构造函数Planet(GLfloat radius, GLfloat distance,GLfloat speed, GLfloat selfSpeed,Star* parent, GLfloat rgbColor[3]);// 增加对具备自身材质的行星绘制材质void drawPlanet();// 继续向其子类开放重写功能virtual void draw() { drawPlanet(); drawStar(); }};class LightPlanet : public Planet {public:LightPlanet(GLfloat Radius, GLfloat Distance,GLfloat Speed, GLfloat SelfSpeed,Star* Parent, GLfloat rgbColor[]);// 增加对提供光源的恒星绘制光照void drawLight();virtual void draw() { drawLight(); drawPlanet(); drawStar(); }};在太阳系中,太阳系显然是由各个行星组成的;并且,对于太阳系而言,太阳系中行星运动后的视图刷新应该由太阳系来完成。据此太阳系成员变量应为包含行星的变量,成员函数应作为处理太阳系内的视图刷新及键盘响应等事件,所以,我们可以设计 
SolarSystem
 类:class SolarSystem {public:SolarSystem();~SolarSystem();void onDisplay();void onUpdate();void onKeyboard(unsigned char key, int x, int y);private:Star *stars[STARS_NUM];// 定义观察视角的参数GLdouble viewX, viewY, viewZ;GLdouble centerX, centerY, centerZ;GLdouble upX, upY, upZ;};程序的基本框架:main.cpp// main.cpp#include <GL/glut.h>#include "solarsystem.hpp"#define WINDOW_X_POS 50#define WINDOW_Y_POS 50#define WIDTH 700#define HEIGHT 700SolarSystem solarsystem;//实例化一个太阳系void onDisplay(void) {solarsystem.onDisplay();}void onUpdate(void) {solarsystem.onUpdate();}void onKeyboard(unsigned char key, int x, int y) {solarsystem.onKeyboard(key, x, y);}int main(int argc, char* argv[]) {glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);glutInitWindowPosition(WINDOW_X_POS, WINDOW_Y_POS);glutCreateWindow("SolarSystem at Shiyanlou");glutDisplayFunc(onDisplay);glutIdleFunc(onUpdate);glutKeyboardFunc(onKeyboard);glutMainLoop();return 0;}本实验框架及思路来自实验楼,运行的效果如下图所示:

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: