QAM add constellation plot
This commit is contained in:
113
plot/plot_constellation.c
Normal file
113
plot/plot_constellation.c
Normal file
@ -0,0 +1,113 @@
|
||||
#include "plot_constellation.h"
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
35
plot/plot_constellation.h
Normal file
35
plot/plot_constellation.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef PLOT_CONSTELLATION_H
|
||||
#define PLOT_CONSTELLATION_H
|
||||
|
||||
#include <complex.h>
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
typedef struct {
|
||||
SDL_Window *window;
|
||||
SDL_Renderer *renderer;
|
||||
int width;
|
||||
int height;
|
||||
double scale;
|
||||
double offset_x;
|
||||
double offset_y;
|
||||
} plot_t;
|
||||
|
||||
// Initialiser SDL et la fenêtre
|
||||
void plot_init(plot_t *plot, int width, int height, double scale);
|
||||
|
||||
// Dessiner la constellation (grille de départ)
|
||||
void plot_draw_constellation(plot_t *plot, double complex **constellation, int M);
|
||||
|
||||
// Dessiner un tableau de points complexes
|
||||
void plot_draw_points(plot_t *plot, double complex *points, int nb_points, SDL_Color color);
|
||||
|
||||
// Dessiner les points progressivement avec animation
|
||||
// delay_ms = délai entre chaque point en millisecondes
|
||||
// Keypress pendant animation coupe l’animation
|
||||
void plot_draw_points_animated(plot_t *plot, double complex *points, int nb_points, SDL_Color color, int delay_ms);
|
||||
|
||||
// Fermer SDL proprement
|
||||
void plot_close(plot_t *plot);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user