├── LICENSE ├── Makefile ├── README.md ├── galaxy.c ├── hsv.c ├── ss.png └── star.png /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Brandon Blake 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | FILENAME=galaxy 2 | SRCNAME=galaxy.c 3 | STD=gnu11 4 | 5 | all: $(FILENAME) 6 | 7 | release: win32 *.c 8 | clang $(SRCNAME) -o$(FILENAME) -std=$(STD) -lSDL2 -lSDL2_image -lm -lz -Wall -O2 9 | 10 | $(FILENAME): *.c 11 | clang $(SRCNAME) -o$(FILENAME) -std=$(STD) -lSDL2 -lSDL2_image -lm -lz -Wall -O0 -g 12 | 13 | run: $(FILENAME) 14 | ./$(FILENAME) 15 | 16 | win32: 17 | i686-w64-mingw32-gcc $(SRCNAME) -owindows/$(FILENAME).exe -std=$(STD) `i686-w64-mingw32-sdl2-config --libs` `i686-w64-mingw32-pkg-config SDL2_image --libs` -lm -lz -Wall -O2 18 | 19 | .PHONY: all run 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | GALAXY 2 | ====== 3 | 4 | Random Galaxy Generator: Pops up a window with a random galaxy! 5 | 6 | ![A Randomly Generated Galaxy](./ss.png) 7 | 8 | Requirements 9 | ------------- 10 | 11 | * SDL 2.0 12 | * SDL Image 13 | * LibPNG 14 | * Gnu Make 15 | * Clang 16 | 17 | Configuration 18 | ------------- 19 | 20 | No config for now, you can just root around in `galaxy.c`. 21 | 22 | 23 | Usage 24 | --------- 25 | 26 | make run 27 | 28 | or 29 | 30 | make 31 | ./galaxy 32 | 33 | -------------------------------------------------------------------------------- /galaxy.c: -------------------------------------------------------------------------------- 1 | #define SDL_MAIN_HANDLED 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "hsv.c" 12 | 13 | SDL_Window* window; 14 | SDL_Renderer* renderer; 15 | 16 | // Config 17 | const double radius = 64; // ly 18 | const double star_num = 100; // Probability correlation 19 | const int screen_size = 1024; 20 | 21 | // Randomised Values 22 | // ================= 23 | double twistval; // rad/ly 24 | double tiltval; 25 | double angle; 26 | double ab; // Major axis / minor axis of stellar orbits 27 | 28 | rgb star_color; 29 | 30 | // ================= 31 | 32 | struct Point { 33 | double x; 34 | double y; 35 | }; 36 | 37 | struct PointPolar { 38 | double r; 39 | double phi; 40 | }; 41 | 42 | static SDL_Texture *tex_star; 43 | 44 | // Random float in [-1.0, 1.0] 45 | double drand() { 46 | return rand() / (double)RAND_MAX * 2.0 - 1.0; 47 | } 48 | 49 | void 50 | init() { 51 | srand(getpid()); 52 | 53 | //Check SDL Version 54 | SDL_version compiled; 55 | SDL_version linked; 56 | SDL_VERSION(&compiled); 57 | SDL_GetVersion(&linked); 58 | if (compiled.major != linked.major) { 59 | fprintf(stderr, "SDL version mismatch! Found version %d, require version %d", linked.major, compiled.major); 60 | exit(EXIT_FAILURE); 61 | } 62 | 63 | 64 | if(SDL_Init(SDL_INIT_VIDEO)) { 65 | fprintf(stderr, "Initialisation Error: %s", SDL_GetError()); 66 | exit(EXIT_FAILURE); 67 | } 68 | 69 | if(SDL_CreateWindowAndRenderer(screen_size, screen_size, SDL_WINDOW_BORDERLESS, &window, &renderer)) { 70 | fprintf(stderr, "Window creation failed: %s", SDL_GetError()); 71 | exit(EXIT_FAILURE); 72 | } 73 | 74 | if(IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG) == 0) { 75 | printf("Failed to load image libraries: %s\n", IMG_GetError()); 76 | } else { 77 | tex_star = IMG_LoadTexture(renderer, "./star.png"); 78 | if(!tex_star) { 79 | printf("Couldn't load star image: %s\n", IMG_GetError()); 80 | } else { 81 | SDL_SetTextureBlendMode(tex_star, SDL_BLENDMODE_ADD); 82 | hsv randcolor; 83 | randcolor.h = fabs(drand()) * 360.0; 84 | randcolor.s = 0.75; 85 | randcolor.v = 1; 86 | star_color = hsv_to_rgb(randcolor); 87 | SDL_SetTextureColorMod(tex_star, star_color.r, star_color.g, star_color.b); 88 | } 89 | } 90 | 91 | SDL_SetWindowTitle(window, "Galaxy"); 92 | 93 | // Settings 94 | SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_ADD); 95 | // Hints 96 | SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); 97 | 98 | twistval = 1.0/256*M_PI * (1 + drand() * 0.1); //+- 10% 99 | ab = 1.2 * (1 + drand() * 0.1); 100 | tiltval = fabs(drand()); 101 | angle = 2*M_PI*fabs(drand()); 102 | 103 | } 104 | 105 | void 106 | quit(int exit_code) { 107 | SDL_Quit(); 108 | exit(exit_code); 109 | } 110 | 111 | void 112 | wait_for_key(SDL_Keycode sym) { 113 | bool wait = true; 114 | SDL_Event event; 115 | while(wait) { 116 | while(SDL_PollEvent(&event)) { 117 | if(event.type == SDL_KEYDOWN) { 118 | if(event.key.keysym.sym == sym) { 119 | wait = false; 120 | } 121 | } else if(event.type == SDL_QUIT) { 122 | quit(EXIT_SUCCESS); 123 | } 124 | } 125 | SDL_RenderPresent(renderer); 126 | SDL_Delay(16); 127 | } 128 | } 129 | 130 | struct Point 131 | polar_to_cart(struct PointPolar pp) { 132 | struct Point p; 133 | p.x = pp.r*cos(pp.phi); 134 | p.y = pp.r*sin(pp.phi); 135 | return p; 136 | } 137 | 138 | struct PointPolar 139 | cart_to_polar(struct Point p) { 140 | struct PointPolar pp; 141 | pp.r = sqrt(p.x*p.x + p.y*p.y); 142 | pp.phi = atan2(p.y, p.x); 143 | return pp; 144 | } 145 | 146 | double 147 | pdf(struct PointPolar pp) { 148 | double val = 1/radius * exp(-pp.r/radius); 149 | //printf("Pdf = %.100f\n", val); 150 | return val; 151 | } 152 | 153 | struct PointPolar 154 | twist(struct PointPolar pin) { 155 | struct PointPolar pout; 156 | pout.r = pin.r; 157 | pout.phi = pin.phi; 158 | double a = ab*pin.r; 159 | double b = pin.r; 160 | //"Ellipse Number" 161 | double en = a*b/(sqrt(pow(b * cos(pin.phi), 2) + pow(a * sin(pin.phi), 2))); 162 | pout.phi = pin.phi + twistval * en; 163 | return pout; 164 | } 165 | 166 | struct Point tilt(struct Point p, double tiltval) { 167 | p.y *= tiltval; 168 | return p; 169 | } 170 | 171 | struct Point rotate(struct Point p, double rads) { 172 | struct PointPolar pp = cart_to_polar(p); 173 | pp.phi += rads; 174 | return polar_to_cart(pp); 175 | } 176 | 177 | void draw_star(SDL_Renderer *renderer, int x, int y) { 178 | if(tex_star) { 179 | SDL_RenderCopy(renderer, tex_star, NULL, &(SDL_Rect){x - 1, y - 1, 3, 3}); 180 | } else { 181 | SDL_RenderDrawPoint(renderer, x, y); 182 | } 183 | //SDL_RenderFillRect(renderer, &(SDL_Rect){x-1, y-1, 3, 3}); 184 | } 185 | 186 | int 187 | main(int argc, char **argv) { 188 | init(); 189 | 190 | 191 | SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); 192 | SDL_RenderClear(renderer); 193 | 194 | int star_count = 0; 195 | 196 | SDL_SetRenderDrawColor(renderer, 255, 255, 255, 1); 197 | for(double y = -screen_size/2; y < screen_size/2; y++) { 198 | for(double x = -screen_size/2; x < screen_size/2; x++) { 199 | double randval = (rand() / (double)RAND_MAX) / star_num; 200 | struct PointPolar pp = cart_to_polar((struct Point){x, y}); 201 | if(pdf(pp) > randval) { 202 | struct Point p = rotate(tilt(polar_to_cart(twist(pp)), tiltval), angle); 203 | draw_star(renderer, p.x + screen_size/2, p.y + screen_size/2); 204 | star_count++; 205 | } 206 | ////Alternative: Set brightness (smooth galaxy), factor is no good 207 | //int i = 1e6*pdf(pp); 208 | //SDL_SetRenderDrawColor(renderer, I,I,I,255); 209 | //struct Point p = polar_to_cart(twist(pp)); 210 | //SDL_RenderDrawPoint(renderer, p.x + screen_size/2, p.y + screen_size/2); 211 | } 212 | } 213 | 214 | SDL_RenderPresent(renderer); 215 | printf("%d stars\n", star_count); 216 | 217 | wait_for_key(SDLK_ESCAPE); 218 | return 0; 219 | } 220 | -------------------------------------------------------------------------------- /hsv.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | struct fColor { 4 | union { 5 | struct { 6 | double r; 7 | double g; 8 | double b; 9 | }; 10 | struct { 11 | double h; // 0.0 → 360.0 12 | double s; 13 | double v; 14 | }; 15 | }; 16 | }; 17 | 18 | typedef struct fColor rgb; 19 | typedef struct fColor hsv; 20 | 21 | // "Adopted" wholesale from Stackoverflow user David H 22 | 23 | rgb hsv_to_rgb(hsv in) 24 | { 25 | double hh, p, q, t, ff; 26 | long i; 27 | rgb out; 28 | 29 | if(in.s <= 0.0) { // < is bogus, just shuts up warnings 30 | out.r = in.v; 31 | out.g = in.v; 32 | out.b = in.v; 33 | return out; 34 | } 35 | hh = in.h; 36 | if(hh >= 360.0) hh = 0.0; 37 | hh /= 60.0; 38 | i = (long)hh; 39 | ff = hh - i; 40 | p = in.v * (1.0 - in.s); 41 | q = in.v * (1.0 - (in.s * ff)); 42 | t = in.v * (1.0 - (in.s * (1.0 - ff))); 43 | 44 | switch(i) { 45 | case 0: 46 | out.r = in.v; 47 | out.g = t; 48 | out.b = p; 49 | break; 50 | case 1: 51 | out.r = q; 52 | out.g = in.v; 53 | out.b = p; 54 | break; 55 | case 2: 56 | out.r = p; 57 | out.g = in.v; 58 | out.b = t; 59 | break; 60 | 61 | case 3: 62 | out.r = p; 63 | out.g = q; 64 | out.b = in.v; 65 | break; 66 | case 4: 67 | out.r = t; 68 | out.g = p; 69 | out.b = in.v; 70 | break; 71 | case 5: 72 | default: 73 | out.r = in.v; 74 | out.g = p; 75 | out.b = q; 76 | break; 77 | } 78 | 79 | out.r *= 255; 80 | out.g *= 255; 81 | out.b *= 255; 82 | return out; 83 | } 84 | -------------------------------------------------------------------------------- /ss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brisk0/galaxy/f05e01fd61ccbd7374b6ee1eba4b9686e5a16710/ss.png -------------------------------------------------------------------------------- /star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brisk0/galaxy/f05e01fd61ccbd7374b6ee1eba4b9686e5a16710/star.png --------------------------------------------------------------------------------