Select Git revision
planet.c 5.76 KiB
#include "planet.h"
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
//Masse (kg)
#define G 6.67e-11
#define M_SOLEIL 1.989e30
#define M_MERCURE 3.285e23
#define M_VENUS 4.867e24
#define M_TERRE 5.972e24
#define M_MARS 6.39e23
#define M_NAMEK 1.40e25
#define M_AZEROTH 7.20e25
// e = excentricité ; DG = demi-grand axe ; peri = périhelie
planet_t create_planet(double mass, vec2 pos, vec2 prec_pos, double e, double DG, double peri){
planet_t p;
p.mass = mass;
p.pos = pos;
p.prec_pos = prec_pos;
p.e = e;
p.DG = DG;
p.peri = peri;
return p;
}
//distances en m
system_t create_system(){
system_t s;
s.star = create_planet(M_SOLEIL , vec2_create_zero(), vec2_create_zero(), 0, 0, 0);
s.nb_planets = 6;
s.planets = malloc(sizeof(planet_t) * s.nb_planets);
s.planets[0] = create_planet(M_MERCURE , vec2_create(-46000000000, 0), vec2_create(0 , 0), 0.20563069, 57909050000, 46000000000);
s.planets[1] = create_planet(M_VENUS , vec2_create(-107476170000, 0), vec2_create(0 , 0), 0.0067733, 108208475000, 107476170000);
s.planets[2] = create_planet(M_TERRE, vec2_create(-147098291000 , 0), vec2_create(0 , 0), 0.01671022, 149598023000, 147098291000);
s.planets[3] = create_planet(M_MARS , vec2_create(-206655215000 , 0), vec2_create(0 , 0), 0.09341233, 227939200000, 206655215000);
s.planets[4] = create_planet(M_NAMEK , vec2_create(-236000000000, 0), vec2_create(0 , 0), 0.01, 243000000000, 236000000000);
s.planets[5] = create_planet(M_AZEROTH , vec2_create(-320000000000 , 0), vec2_create(0 , 0), 0.01, 330000000000, 320000000000);
return s;
}
//affichage des planetes, rayon a l'échelle 1/ 1 000 000 m
void show_system(struct gfx_context_t *ctxt, system_t *system){
draw_full_circle(ctxt, 500, 500, 7, COLOR_YELLOW);
draw_full_circle(ctxt, 500, 500, 5, COLOR_ORANGE);
draw_full_circle(ctxt, 500, 500, 3, COLOR_RED);
draw_full_circle(ctxt, 500, 500, 1, COLOR_BLACK);
int posx[system->nb_planets];
int posy[system->nb_planets];
int rayon[system->nb_planets];
int couleur[system->nb_planets];
for(int i = 0; i < system->nb_planets ; i++){
double mass = system->planets[i].mass;
coordinates coord = vec2_to_coordinates(system->planets[i].pos);
if(mass == M_NAMEK){
posx[i] = coord.column;
posy[i] = coord.row;
rayon[i] = 3;
couleur[i] = COLOR_GREEN;
}
else if(mass == M_MERCURE){
posx[i] = coord.column;
posy[i] = coord.row;
rayon[i] = 2.439;
couleur[i] = COLOR_WHITE;
}
else if(mass == M_VENUS){
posx[i] = coord.column;
posy[i] = coord.row;
rayon[i]= 6.051;
couleur[i] = COLOR_ORANGE;
}
else if(mass == M_TERRE){
posx[i] = coord.column;
posy[i] = coord.row;
rayon[i] = 6.371;
couleur[i] = COLOR_BLUE;
}
else if(mass == M_MARS){
posx[i] = coord.column;
posy[i] = coord.row;
rayon[i] = 6.991;
couleur[i] = COLOR_RED;
}
else{
posx[i] = coord.column;
posy[i] = coord.row;
rayon[i] = 10.45;
couleur[i] = COLOR_TURQUOISE;
}
}
for(int i = 0 ; i < system->nb_planets ; i++){
draw_full_circle(ctxt, posx[i], posy[i], rayon[i], couleur[i]);
}
}
//update du systeme
void update_system(system_t *system, double delta_t, bool x){
for(int i = 0; i < system->nb_planets ; i++){
vec2 pos_tmp = system->planets[i].pos;
if(!x){
system->planets[i].pos = pos_init(*system, system->planets[i] , delta_t);
if(i == system->nb_planets){
x = true;
}
}
else{
system->planets[i].pos = pos_u(*system, system->planets[i] , delta_t);
}
system->planets[i].prec_pos = pos_tmp;
}
}
//booleene pour qu'une planete ne boucle pas sur elle même
bool is_equal(planet_t a, planet_t b){
return a.mass == b.mass;
}
//force de gravité
vec2 gravite(planet_t a, planet_t b){
vec2 AB = vec2_sub(a.pos, b.pos);
vec2 fBA;
fBA.x = G * ((a.mass * b.mass) / pow(vec2_norm(AB), 3)) * AB.x;
fBA.y = G * ((a.mass * b.mass) / pow(vec2_norm(AB), 3)) * AB.y;
return fBA;
}
//force résultante
vec2 somme_force(system_t system, planet_t p){
vec2 s = gravite(p, system.star);
for(int i = 0 ; i < system.nb_planets ; i++){
if(!is_equal(p , system.planets[i])){
vec2 g = gravite(p, system.planets[i]);
s.x += g.x;
s.y += g.y;
}
}
return s;
}
//acceleration
vec2 accel(system_t system, planet_t p){
vec2 a = somme_force(system , p);
double x = a.x / p.mass;
double y = a.y / p.mass;
return vec2_create(x, y);
}
//vitesse initiale
vec2 vitesse_i(planet_t p){
vec2 per = vec2_create(-p.pos.y , p.pos.x);
double x = sqrt((G * M_SOLEIL * (1 + p.e)) / (p.DG * (1-p.e))) * per.x / vec2_norm(per);
double y = sqrt((G * M_SOLEIL * (1 + p.e)) / (p.DG * (1-p.e))) * per.y / vec2_norm(per);;
return vec2_create(x, y);
}
//premier changement de position
vec2 pos_init(system_t system, planet_t p, double delta_t){
vec2 v = vitesse_i(p);
vec2 a = accel(system , p);
double x = p.pos.x + delta_t * v.x + (pow(delta_t, 2) / 2) * a.x;
double y = p.pos.y + delta_t * v.y + (pow(delta_t, 2) / 2) * a.y;
return vec2_create(x, y);
}
//position update
vec2 pos_u(system_t system, planet_t p, double delta_t){
vec2 a = accel(system , p);
double x = 2 * p.pos.x - p.prec_pos.x + pow(delta_t, 2) * a.x;
double y = 2 * p.pos.y - p.prec_pos.y + pow(delta_t, 2) * a.y;
return vec2_create(x, y);
}