#include "plot_constellation.h" #include #include #include // Fonction utilitaire pour dessiner un cercle plein static void draw_filled_circle(SDL_Renderer* renderer, int cx, int cy, int radius) { for (int w = -radius; w <= radius; w++) { for (int h = -radius; h <= radius; h++) { if (w*w + h*h <= radius*radius) { SDL_RenderDrawPoint(renderer, cx + w, cy + h); } } } } // Initialisation SDL void plot_init(plot_t *plot, int width, int height, double scale) { if (SDL_Init(SDL_INIT_VIDEO) != 0) { fprintf(stderr, "Erreur SDL_Init: %s\n", SDL_GetError()); exit(1); } plot->width = width; plot->height = height; plot->scale = scale; plot->offset_x = width / 2.0; plot->offset_y = height / 2.0; plot->window = SDL_CreateWindow("Constellation QAM", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_SHOWN); if (!plot->window) { fprintf(stderr, "Erreur SDL_CreateWindow: %s\n", SDL_GetError()); exit(1); } plot->renderer = SDL_CreateRenderer(plot->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if (!plot->renderer) { fprintf(stderr, "Erreur SDL_CreateRenderer: %s\n", SDL_GetError()); exit(1); } SDL_SetRenderDrawColor(plot->renderer, 0, 0, 0, 255); // fond noir SDL_RenderClear(plot->renderer); SDL_RenderPresent(plot->renderer); } // Dessiner la constellation (grille verte) void plot_draw_constellation(plot_t *plot, double complex **constellation, int M) { int sm = (int)sqrt(M); SDL_SetRenderDrawColor(plot->renderer, 0, 255, 0, 255); // vert int radius = 8; // gros cercle pour la grille for (int i = 0; i < sm; i++) { for (int j = 0; j < sm; j++) { int x = (int)(creal(constellation[i][j]) * plot->scale + plot->offset_x); int y = (int)(cimag(constellation[i][j]) * plot->scale + plot->offset_y); draw_filled_circle(plot->renderer, x, y, radius); } } SDL_RenderPresent(plot->renderer); } // Dessiner un tableau de points complexes (rouges) void plot_draw_points(plot_t *plot, double complex *points, int nb_points, SDL_Color color) { int radius = 4; // plus petit que la grille verte SDL_SetRenderDrawColor(plot->renderer, color.r, color.g, color.b, color.a); for (int k = 0; k < nb_points; k++) { int x = (int)(creal(points[k]) * plot->scale + plot->offset_x); int y = (int)(cimag(points[k]) * plot->scale + plot->offset_y); draw_filled_circle(plot->renderer, x, y, radius); } SDL_RenderPresent(plot->renderer); } // Dessiner les points progressivement avec animation void plot_draw_points_animated(plot_t *plot, double complex *points, int nb_points, SDL_Color color, int delay_ms) { int radius = 4; int k; for (k = 0; k < nb_points; k++) { SDL_SetRenderDrawColor(plot->renderer, color.r, color.g, color.b, color.a); int x = (int)(creal(points[k]) * plot->scale + plot->offset_x); int y = (int)(cimag(points[k]) * plot->scale + plot->offset_y); draw_filled_circle(plot->renderer, x, y, radius); SDL_RenderPresent(plot->renderer); // Gestion événements pour stopper animation SDL_Event event; int stop = 0; while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) return; if (event.type == SDL_KEYDOWN) { stop = 1; break; } } if (stop) break; SDL_Delay(delay_ms); } // Après animation ou keypress, attendre fermeture ou keypress int running = 1; SDL_Event event; while (running) { while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) running = 0; if (event.type == SDL_KEYDOWN) running = 0; } SDL_Delay(10); } } // Fermer SDL void plot_close(plot_t *plot) { SDL_DestroyRenderer(plot->renderer); SDL_DestroyWindow(plot->window); SDL_Quit(); }