Reputation: 13
I am currently making a simple solar system orbit program. So far I have managed to display the planets and sun in the window however I have yet to figure out how to get the time based circular motion needed for the planets. The motion is just a simple circle no in depth physics. My code below will show the class for the earth (no other planets at the moment) and how the time function works and the original straight motion I also found online to see how motion could work in c++. I have seen many different equations online but I am unsure on how to implement them into the code.
Earth Header:
#ifndef Earth_H_
#define Earth_H_
#include "Entity.h"
#include <math.h>
// Define a Sun speed in pixels per second
//const double Degree= 180/ M_PI;
class Earth : public Entity {
const float Earth_Speed = 100;
public:
Earth(SDL_Renderer* renderer);
~Earth();
void Update(float delta);
void Render(float delta);
void SetDirection(float dirx, float diry);
const double Degree = 180 / M_PI;
/*float Orbital_Speed=0.01;*/
double Angle;
/*float Speed= 900;*/
double Radius=100;
float dirx, diry;
private:
SDL_Texture* texture;
};
#endif
Earth cpp:
#include "Earth.h"
Earth::Earth(SDL_Renderer* renderer) : Entity(renderer) {
SDL_Surface* surface = IMG_Load("Earth.png");
texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);
x = 0;
y = 0;
width = 20;
height = 20;
}
Earth::~Earth() {
// Clean resources
SDL_DestroyTexture(texture);
}
void Earth::Update(float delta) {
// Move the Sun, time based
x += dirx * delta;
y += diry * delta;
//Angle = atan2(diry / Degree, dirx / Degree);
//x += ((dirx*Degree) - cos(Angle)*Radius)* delta;
//y += ((diry*Degree) - sin(Angle)*Radius)* delta;
}
void Earth::Render(float delta) {
SDL_Rect rect;
rect.x = (int)(x + 0.5f); // Round the float to the nearest integer
rect.y = (int)(y + 0.5f); // Round the float to the nearest integer
rect.w = width;
rect.h = height;
SDL_RenderCopy(renderer, texture, 0, &rect);
}
void Earth::SetDirection(float dirx, float diry) {
//Angle = atan2(diry/ Degree, dirx/ Degree);
//this->dirx = ((dirx*Degree) - cos(Angle)*Radius)*Earth_Speed;
//this->diry = ((diry*Degree) - sin(Angle)*Radius)*Earth_Speed;
float length = sqrt(dirx * dirx + diry * diry);
this->dirx = Earth_Speed * (dirx / length);
this->diry = Earth_Speed * (diry / length);
}
Simulation Header:
#ifndef Simulation_H_
#define Simulation_H_
#include "SDL.h"
#include "SDL_image.h"
#include <iostream>
#include <vector>
#include "Sun.h"
#include "Mercury.h"
#include "Venus.h"
#include "Earth.h"
#include "Mars.h"
#include "Jupiter.h"
#include "Saturn.h"
#include "Uranus.h"
#include "Neptune.h"
#define FPS_DELAY 500
class Simulation {
public:
Simulation();
~Simulation();
bool Init();
void Run();
private:
SDL_Window* window;
SDL_Renderer* renderer;
// Timing
unsigned int lasttick, fpstick, fps, framecount;
float width= 650, height= 650;
Sun* sun;
Mercury* mercury;
Venus* venus;
Earth* earth;
Mars* mars;
Jupiter* jupiter;
Saturn* saturn;
Uranus* uranus;
Neptune* neptune;
void Clean();
void Update(float delta);
void Render(float delta);
void NewSimulation();
};
#endif
Simulation cpp:
#include "Simulation.h"
Simulation::Simulation() {
window = 0;
renderer = 0;
}
Simulation::~Simulation() {
}
bool Simulation::Init() {
// Initialize SDL and the video subsystem
SDL_Init(SDL_INIT_VIDEO);
// Create window
window = SDL_CreateWindow("Suraj's Solar System Simulator",
100, 100,
width, height, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
if (!window) {
// Error creating window
return false;
}
// Create renderer
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (!renderer) {
// Error creating renderer
return false;
}
// Initialize timing
lasttick = SDL_GetTicks();
return true;
}
void Simulation::Clean() {
// Clean renderer and window
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
}
void Simulation::Run() {
// Create Sun and Planets
sun = new Sun(renderer);
mercury = new Mercury(renderer);
venus= new Venus(renderer);
earth = new Earth(renderer);
mars= new Mars(renderer);
jupiter = new Jupiter(renderer);
saturn = new Saturn(renderer);
uranus = new Uranus(renderer);
neptune = new Neptune(renderer);
NewSimulation();
// Main loop
while (1) {
// Handler events
SDL_Event e;
if (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT) {
break;
}
}
// Calculate delta and fps
unsigned int curtick = SDL_GetTicks();
float delta = (curtick - lasttick) / 1000.0f;
lasttick = curtick;
// Update and render the Simulation
Update(delta);
Render(delta);
}
// Delete objects
delete sun;
delete mercury;
delete venus;
delete earth;
delete mars;
delete jupiter;
delete saturn;
delete uranus;
delete neptune;
Clean();
SDL_Quit();
}
void Simulation::NewSimulation() {
// Center the Sun horizontally and vertically
sun->x = width / 2 - sun->width / 2;
sun->y = height / 2 - sun->height / 2;
mercury->x = width / 2.4 - mercury->width / 2.4;
mercury->y = height / 2 - mercury->height / 2;
venus->x = width / 2.7 - venus->width / 2.7;
venus->y = height / 2 - venus->height / 2;
earth->x = width / 3 - earth->width / 3;
earth->y = height / 2 - earth->height / 2;
mars->x = width / 3.4 - mars->width / 3.4;
mars->y = height / 2 - mars->height / 2;
jupiter->x = width / 5 - jupiter->width / 5;
jupiter->y = height / 2 - jupiter->height / 2;
saturn->x = width / 9- saturn->width / 9;
saturn->y = height / 2 - saturn->height / 2;
uranus->x = width / 15 - uranus->width / 15;
uranus->y = height / 2 - uranus->height / 2;
neptune->x = width / 50 - neptune->width / 50;
neptune->y = height / 2 - neptune->height / 2;
//// Set the initial direction of the planets
/*mercury->SetDirection(1, -1);
venus->SetDirection(1, -1);*/
earth->SetDirection((earth->x - sun->x)*cos(M_PI/180)+ sun->x, - ((earth->x - sun->x)*sin(M_PI / 180) + sun->y));
//mars->SetDirection(1, -1 );
//jupiter->SetDirection(1, -1);
//saturn->SetDirection(1, -1);
//uranus->SetDirection(1, -1);
//neptune->SetDirection(1, -1);
}
void Simulation::Update(float delta) {
// Update Earth and Sun
sun->Update(delta);
mercury->Update(delta);
venus->Update(delta);
earth->Update(delta);
mars->Update(delta);
jupiter->Update(delta);
saturn->Update(delta);
uranus->Update(delta);
neptune->Update(delta);
}
void Simulation::Render(float delta) {
// Clear the screen to black
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
// Render board and Sun
sun->Render(delta);
mercury->Render(delta);
venus->Render(delta);
earth->Render(delta);
mars->Render(delta);
jupiter->Render(delta);
saturn->Render(delta);
uranus->Render(delta);
neptune->Render(delta);
// Update the screen
SDL_RenderPresent(renderer);
}
Entity Header:
#ifndef ENTITY_H_
#define ENTITY_H_
#include "SDL.h"
#include "SDL_image.h"
class Entity {
public:
Entity(SDL_Renderer* renderer);
virtual ~Entity();
float x, y, width, height;
virtual void Update(float delta);
virtual void Render(float delta);
protected:
SDL_Renderer* renderer;
};
#endif
Enitity cpp:
#include "Entity.h"
Entity::Entity(SDL_Renderer* renderer) {
this->renderer = renderer;
x = 0;
y = 0;
width = 1;
height = 1;
}
Entity::~Entity() {
}
void Entity::Update(float delta) {
}
void Entity::Render(float delta) {
}
Main Header:
#ifndef MAIN_H_
#define MAIN_H_
#include "Simulation.h"
int main(int argc, char* argv[]);
#endif
Main cpp:
#include "main.h"
int main(int argc, char* argv[]) {
// Create the game object
Simulation* simulation = new Simulation();
// Initialize and run the game
if (simulation->Init()) {
simulation->Run();
}
// Clean up
delete simulation;
return 0;
}
Upvotes: 0
Views: 1902
Reputation: 7644
circular motion is usually accomplished with:
angle += orbit_speed * delta_time;
x = center_x + radius * cos(angle);
y = center_y + radius * sin(angle);
Upvotes: 2