aboutsummaryrefslogtreecommitdiff
path: root/src/2-5-grav-attraction.c
blob: e4e03132385655ee7bdfd04c6dc77c653aac7888 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <SDL2/SDL_render.h>
#include <stdbool.h>
#include <vectorlib.c>

#include <SDL2/SDL.h>
#include <SDL2/SDL_video.h>
#include <SDL2/SDL2_gfxPrimitives.h>

#define PROJECT_NAME "vectors-gravity attraction"
#define obj_n 10

typedef struct ATTRACTOR {
    Point pos;
    float r;
    float mass;
} ATTRACTOR;

typedef struct OBJECT_INER {
    Point pos;
    Point vel;
    Point acc;
    float r;
    float mass;
} OBJECT_INER;

typedef struct OBJECT {
    ATTRACTOR attractor;
    OBJECT_INER *objs[obj_n];
} OBJECT;

#include <init.h>

void constructor(int w, int h, OBJECT_INER *obj, float x, float y, float mass){
    obj->pos.x = x;
    obj->pos.y = y;
    obj->vel = (Point){RandomFloat(-1, 1),RandomFloat(-1, 1)};
    point_mul(&obj->vel,&(Point){5,5});
    obj->acc = (Point){0,0};
    obj->mass = mass;
    obj->r = sqrt(obj->mass) * 2;
}

void attractor_constructor(int w, int h, ATTRACTOR *attractor, float x, float y, float mass){
    attractor->pos.x = x;
    attractor->pos.y = y;
    attractor->mass = mass;
    attractor->r = sqrt(attractor->mass) * 2;
}

void init_stuffs(int w, int h, OBJECT_INER *objs,STUFFS *stuff){
    for (int i=0; i<obj_n; i++){
        constructor(w, h, &objs[i], RandomFloat(0, w), RandomFloat(0, h), RandomFloat(50, 150));
    }
    attractor_constructor(w,h,&stuff->obj.attractor,(float)w/2,(float)h/2,100);
}

void applyForce(OBJECT_INER *obj, Point force){
    point_div(&force, &(Point){obj->mass,obj->mass});
    point_add(&obj->acc, &force);
}

void update(STUFFS *stuff, OBJECT_INER *obj){
    point_add(&obj->vel,&obj->acc);
    point_add(&obj->pos, &obj->vel);
    obj->acc = (Point){0,0};
}

void show(SDL_Renderer* renderer,STUFFS *stuff,OBJECT_INER *obj){
    Sint16 x = (Sint16)obj->pos.x;
    Sint16 y = (Sint16)obj->pos.y;

    circleRGBA(renderer, x, y, obj->r, 190, 90, 255, 255);
    filledCircleRGBA(renderer, x, y, obj->r, 150, 50, 255, 80);
}

void attract(ATTRACTOR *attractor, OBJECT_INER *obj){
    Point force = {attractor->pos.x - obj->pos.x, attractor->pos.y - obj->pos.y};
    float dist = magnitude(force.x, force.y);
    dist = dist * dist;
    dist = constrain(dist,100,1000);

    float G = 2;
    float strength = G * (attractor->mass * obj->mass) / dist;

    point_set_mag(&force, strength);
    applyForce(obj,force);
}

void atr_show(SDL_Renderer* renderer,STUFFS *stuff,ATTRACTOR *attr){
    SDL_RenderFillRect(renderer, &(SDL_Rect){attr->pos.x - attr->r, attr->pos.y - attr->r, attr->r*2, attr->r*2});
}

void draw(SDL_Renderer* renderer,SDL_Window* window, STUFFS *stuff){
    SDL_SetRenderDrawColor(renderer,0,0,0,5);
    //SDL_RenderClear(renderer);
    SDL_RenderFillRect(renderer, &(SDL_Rect){0,0,stuff->width,stuff->height});

    for (int i=0; i<obj_n; i++){
        update(stuff,stuff->obj.objs[i]);
        show(renderer,stuff,stuff->obj.objs[i]);

        attract(&stuff->obj.attractor, stuff->obj.objs[i]);
    }
    SDL_SetRenderDrawColor(renderer, 100,20,20,180);
    atr_show(renderer,stuff,&stuff->obj.attractor);

	SDL_RenderPresent(renderer);
}

#include <init.c>