INFO607
Classes | Macros | Typedefs | Functions
main.c File Reference
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <gtk/gtk.h>
#include "points.h"
#include "particules.h"
#include "forces.h"

Go to the source code of this file.

Classes

struct  SContexte
 

Macros

#define DT   0.01
 
#define DT_AFF   0.02
 

Typedefs

typedef struct SContexte Contexte
 

Functions

GtkWidget * creerIHM (Contexte *pCtxt)
 Charge l'image donnée et crée l'interface.
 
gboolean on_draw (GtkWidget *widget, GdkEventExpose *event, gpointer data)
 
Point point2DrawingAreaPoint (Contexte *pCtxt, Point p)
 
double length2DrawingAreaLength (Contexte *pCtxt, double l)
 
Point drawingAreaPoint2Point (Contexte *pCtxt, Point p)
 
void drawParticule (Contexte *pCtxt, cairo_t *cr, Particule p)
 
void drawPoint (cairo_t *cr, double x, double y, double r)
 
gint tic (gpointer data)
 
gint ticAffichage (gpointer data)
 
gint ticDistance (gpointer data)
 
void calculDynamique (Contexte *pCtxt)
 
void deplaceTout (Contexte *pCtxt)
 
void deplaceParticule (Contexte *pCtxt, Particule *p)
 
void fontaine (Contexte *pCtxt, double p, double x, double y, double vx, double vy, double m)
 
int main (int argc, char *argv[])
 
void drawLine (cairo_t *cr, Point p, Point q)
 

Macro Definition Documentation

◆ DT

#define DT   0.01

Definition at line 27 of file main.c.

◆ DT_AFF

#define DT_AFF   0.02

Definition at line 29 of file main.c.

Typedef Documentation

◆ Contexte

typedef struct SContexte Contexte

Le contexte contient les informations utiles de l'interface pour les algorithmes de géométrie algorithmique.

Function Documentation

◆ calculDynamique()

void calculDynamique ( Contexte pCtxt)

Calcul la dynamique de tous les points en appliquant les forces et met à jour la vitesse.

Definition at line 346 of file main.c.

347{
348 TabParticules* P = &pCtxt->TabP;
349 int n = TabParticules_nb( P );
350 Force* F = pCtxt->forces;
351 // On met à zéro les forces de chaque point.
352 for ( int i = 0; i < n; ++i )
353 {
354 Particule* p = TabParticules_ref( P, i );
355 p->f[ 0 ] = 0.0;
356 p->f[ 1 ] = 0.0;
357 }
358 // On applique les forces à tous les points
359 for ( int i = 0; i < n; ++i )
360 {
361 Particule* p = TabParticules_ref( P, i );
362 for ( int j = 0; j < NB_FORCES; ++j )
363 appliqueForce( p, &F[ j ] );
364 }
365 // On applique la loi de Newton: masse*acceleration = somme des forces
366 // ie m dv/dt = sum f
367 // ie v[t+dt] = v[t] + (dt/m) * sum f
368 for ( int i = 0; i < n; ++i )
369 {
370 Particule* p = TabParticules_ref( P, i );
371 p->v[ 0 ] += (DT / p->m) * p->f[ 0 ];
372 p->v[ 1 ] += (DT / p->m) * p->f[ 1 ];
373 }
374}
void appliqueForce(Particule *p, Force *f)
Ajoute à la particule p la force donnée f.
Definition forces.c:12
#define NB_FORCES
Definition forces.h:6
#define DT
Definition main.c:27
int TabParticules_nb(TabParticules *tab)
Definition particules.c:50
Particule * TabParticules_ref(TabParticules *tab, int i)
Definition particules.c:44
Force forces[NB_FORCES]
Definition main.c:21
TabParticules TabP
Definition main.c:20
Une force est un type et des paramètres qui la définissent.
Definition forces.h:11
double f[DIM]
Definition particules.h:11
double v[DIM]
Definition particules.h:10
double m
Definition particules.h:12
Représente un tableau dynamique de particules.
Definition particules.h:23

References appliqueForce(), DT, SParticule::f, SContexte::forces, SParticule::m, NB_FORCES, SContexte::TabP, TabParticules_nb(), TabParticules_ref(), and SParticule::v.

Referenced by tic().

◆ creerIHM()

GtkWidget * creerIHM ( Contexte pCtxt)

Charge l'image donnée et crée l'interface.

Crée l'interface graphique en fonction du contexte pCtxt.

Definition at line 238 of file main.c.

239{
240 GtkWidget* window;
241 GtkWidget* vbox1;
242 GtkWidget* vbox2;
243 GtkWidget* hbox1;
244 GtkWidget* button_quit;
245
246 /* Crée une fenêtre. */
247 window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
248 // Crée un conteneur horizontal box.
249 hbox1 = gtk_box_new( GTK_ORIENTATION_HORIZONTAL, 10 );
250 // Crée deux conteneurs vertical box.
251 vbox1 = gtk_box_new( GTK_ORIENTATION_VERTICAL, 10 );
252 vbox2 = gtk_box_new( GTK_ORIENTATION_VERTICAL, 10 );
253 // Crée une zone de dessin
254 pCtxt->drawing_area = gtk_drawing_area_new();
255 pCtxt->width = 500;
256 pCtxt->height = 500;
257 gtk_widget_set_size_request ( pCtxt->drawing_area, pCtxt->width, pCtxt->height );
258 // Crée le pixbuf source et le pixbuf destination
259 gtk_container_add( GTK_CONTAINER( hbox1 ), pCtxt->drawing_area );
260 // ... votre zone de dessin s'appelle ici "drawing_area"
261 g_signal_connect( G_OBJECT ( pCtxt->drawing_area ), "draw",
262 G_CALLBACK( on_draw ), pCtxt );
263 // Rajoute le 2eme vbox dans le conteneur hbox (pour mettre les boutons sélecteur de points
264 gtk_container_add( GTK_CONTAINER( hbox1 ), vbox2 );
265 // Crée les labels pour afficher le nombre de points et le nombre
266 // d'appel à la fonction distance.
267 pCtxt->label_nb = gtk_label_new( "0 points" );
268 gtk_container_add( GTK_CONTAINER( vbox2 ), pCtxt->label_nb );
269 pCtxt->label_distance = gtk_label_new( "" );
270 gtk_container_add( GTK_CONTAINER( vbox2 ), pCtxt->label_distance );
271
272 // Crée le bouton quitter.
273 button_quit = gtk_button_new_with_label( "Quitter" );
274 // Connecte la réaction gtk_main_quit à l'événement "clic" sur ce bouton.
275 g_signal_connect( button_quit, "clicked",
276 G_CALLBACK( gtk_main_quit ),
277 NULL);
278 // Rajoute tout dans le conteneur vbox.
279 gtk_container_add( GTK_CONTAINER( vbox1 ), hbox1 );
280 gtk_container_add( GTK_CONTAINER( vbox1 ), button_quit );
281 // Rajoute la vbox dans le conteneur window.
282 gtk_container_add( GTK_CONTAINER( window ), vbox1 );
283
284 // Rend tout visible
285 gtk_widget_show_all( window );
286 g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
287
288 // Crée les forces
289 Force g = gravite( 0.0, -0.2 );
290 pCtxt->forces[ 0 ] = g;
291
292 // enclenche le timer pour se déclencher dans 5ms.
293 g_timeout_add ( 1000*DT, tic, (gpointer) pCtxt );
294 // enclenche le timer pour se déclencher dans 20ms.
295 g_timeout_add ( 1000*DT_AFF, ticAffichage, (gpointer) pCtxt );
296 // enclenche le timer pour se déclencher dans 1000ms.
297 g_timeout_add ( 1000, ticDistance, (gpointer) pCtxt );
298
299 return window;
300}
Force gravite(double gx, double gy)
Définit la force de gravité dans la direction donnée.
Definition forces.c:3
#define DT_AFF
Definition main.c:29
gint tic(gpointer data)
Definition main.c:314
gint ticAffichage(gpointer data)
Definition main.c:324
gboolean on_draw(GtkWidget *widget, GdkEventExpose *event, gpointer data)
Definition main.c:163
gint ticDistance(gpointer data)
Definition main.c:335
GtkWidget * label_distance
Definition main.c:23
GtkWidget * drawing_area
Definition convex.c:17
GtkWidget * label_nb
Definition main.c:22

References SContexte::drawing_area, DT, DT_AFF, SContexte::forces, gravite(), SContexte::height, SContexte::label_distance, SContexte::label_nb, on_draw(), tic(), ticAffichage(), ticDistance(), and SContexte::width.

Referenced by main().

◆ deplaceParticule()

void deplaceParticule ( Contexte pCtxt,
Particule p 
)

Déplace une particule en fonction de sa vitesse. Devra s'occuper des collisions plus tard.

Definition at line 376 of file main.c.

377{
378 /* Déplace p en supposant qu'il n'y a pas de collision. */
379 p->x[ 0 ] += DT * p->v[ 0 ];
380 p->x[ 1 ] += DT * p->v[ 1 ];
381}
double x[DIM]
Definition particules.h:9

References DT, SParticule::v, and SParticule::x.

Referenced by deplaceTout().

◆ deplaceTout()

void deplaceTout ( Contexte pCtxt)

Déplace toutes les particules en fonction de leur vitesse.

Definition at line 383 of file main.c.

384{
385 TabParticules* P = &pCtxt->TabP;
386 int n = TabParticules_nb( P );
387 // Applique le vecteur vitesse sur toutes les particules.
388 for ( int i = 0; i < n; ++i )
389 {
390 Particule* p = TabParticules_ref( P, i );
391 deplaceParticule( pCtxt, p );
392 }
393 // Détruit les particules trop loin de la zone
394 for ( int i = 0; i < TabParticules_nb( P ); )
395 {
396 Particule* p = TabParticules_ref( P, i );
397 if ( ( p->x[ 0 ] < -1.5 ) || ( p->x[ 0 ] > 1.5 )
398 || ( p->x[ 1 ] < -1.5 ) || ( p->x[ 1 ] > 1.5 ) )
400 else ++i;
401 }
402}
void deplaceParticule(Contexte *pCtxt, Particule *p)
Definition main.c:376
void TabParticules_supprime(TabParticules *tab, int i)
Definition particules.c:80

References deplaceParticule(), SContexte::TabP, TabParticules_nb(), TabParticules_ref(), TabParticules_supprime(), and SParticule::x.

Referenced by tic().

◆ drawingAreaPoint2Point()

Point drawingAreaPoint2Point ( Contexte pCtxt,
Point  p 
)

Fait la conversion coordonnées pixel de p vers coordonnées réelles.

Parameters
pCtxtle contexte de l'IHM
ples coordonnées pixel en entrée
Returns
ses coordonnées réelles.

Definition at line 205 of file main.c.

206{
207 Point q;
208 q.x[ 0 ] = 2.0 * ((double)p.x[0] / (double)pCtxt->width) - 1.0;
209 q.x[ 1 ] = -2.0 * ((double)p.x[1] / (double)pCtxt->height) + 1.0;
210 return q;
211}
Definition points.h:4
double x
Definition points.h:5

References SContexte::height, SContexte::width, and SPoint::x.

◆ drawLine()

void drawLine ( cairo_t *  cr,
Point  p,
Point  q 
)

Definition at line 230 of file main.c.

231{
232 cairo_move_to( cr, p.x[ 0 ], p.x[ 1 ] );
233 cairo_line_to( cr, q.x[ 0 ], q.x[ 1 ]);
234 cairo_stroke( cr );
235}

References SPoint::x.

◆ drawParticule()

void drawParticule ( Contexte pCtxt,
cairo_t *  cr,
Particule  p 
)

Affiche un point p dans une zone de dessin cairo cr comme un disque. La masse influe sur la taille d'affichage de la particule.

Parameters
crle contexte CAIRO pour dessiner dans une zone de dessin.
pun point dans la zone de dessin.

Definition at line 213 of file main.c.

214{
215 Point pp;
216 pp.x[ 0 ] = p.x[ 0 ];
217 pp.x[ 1 ] = p.x[ 1 ];
218 // On convertit les coordonnées réelles des particules (dans [-1:1]x[-1:1]) en coordonnées
219 // de la zone de dessin (dans [0:499]x[0:499]).
220 Point q = point2DrawingAreaPoint( pCtxt, pp );
221 drawPoint( cr, q.x[ 0 ], q.x[ 1 ], 1.5*sqrt( p.m ) );
222}
void drawPoint(cairo_t *cr, double x, double y, double r)
Definition main.c:224
Point point2DrawingAreaPoint(Contexte *pCtxt, Point p)
Definition main.c:192

References drawPoint(), SParticule::m, point2DrawingAreaPoint(), SPoint::x, and SParticule::x.

Referenced by on_draw().

◆ drawPoint()

void drawPoint ( cairo_t *  cr,
double  x,
double  y,
double  r 
)

Fonction de base qui affiche un disque de centre (x,y) et de rayon r via cairo.

Definition at line 224 of file main.c.

225{
226 cairo_arc( cr, x, y, r, 0.0, 2.0 * 3.14159626 );
227 cairo_fill( cr );
228}

Referenced by drawParticule().

◆ fontaine()

void fontaine ( Contexte pCtxt,
double  p,
double  x,
double  y,
double  vx,
double  vy,
double  m 
)

Fontaine pour créer une particule à la position (x, y), avec la vitesse (vx, vy) et la masse m.

Parameters
pprobabilité (entre 0 et 1) qu'une particule soit effectivement créée.
xla coordonnée x de la position où la particule est créée.
yla coordonnée y de la position où la particule est créée.
vxla composante x de la vitesse de la particule.
vyla composante y de la vitesse de la particule.
mla masse de la particule créée.

Definition at line 302 of file main.c.

304{
305 TabParticules* P = &pCtxt->TabP;
306 if ( ( rand() / (double) RAND_MAX ) < p )
307 {
308 Particule q;
309 initParticule( &q, x, y, vx, vy, m );
310 TabParticules_ajoute( P, q );
311 }
312}
void TabParticules_ajoute(TabParticules *tab, Particule p)
Definition particules.c:25
void initParticule(Particule *p, double x, double y, double vx, double vy, double m)
Definition particules.c:6

References initParticule(), SContexte::TabP, and TabParticules_ajoute().

Referenced by tic().

◆ length2DrawingAreaLength()

double length2DrawingAreaLength ( Contexte pCtxt,
double  l 
)

Fait la conversion longueur réelle l vers longueur en pixel dans la zone de dessin.

Parameters
pCtxtle contexte de l'IHM
lla longueur réelle
Returns
la longueur correspondante en pixels.

Definition at line 200 of file main.c.

201{
202 return pCtxt->width * l / 2.0;
203}

References SContexte::width.

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 144 of file main.c.

146{
147 Contexte context;
148 TabParticules_init( &context.TabP );
149
150 /* Passe les arguments à GTK, pour qu'il extrait ceux qui le concernent. */
151 gtk_init( &argc, &argv );
152
153 /* Crée une fenêtre. */
154 creerIHM( &context );
155
156 /* Rentre dans la boucle d'événements. */
157 gtk_main ();
158 return 0;
159}
GtkWidget * creerIHM(Contexte *pCtxt)
Charge l'image donnée et crée l'interface.
Definition main.c:238
void TabParticules_init(TabParticules *tab)
Definition particules.c:18

References creerIHM(), main(), SContexte::TabP, and TabParticules_init().

◆ on_draw()

gboolean on_draw ( GtkWidget *  widget,
GdkEventExpose *  event,
gpointer  data 
)

c'est la réaction principale qui va redessiner tout.

Definition at line 163 of file main.c.

164{
165 // c'est la réaction principale qui va redessiner tout.
166 Contexte* pCtxt = (Contexte*) data;
167 TabParticules* ptrP = &(pCtxt->TabP);
168 // c'est la structure qui permet d'afficher dans une zone de dessin
169 // via Cairo
170 GdkWindow* window = gtk_widget_get_window(widget);
171 cairo_region_t* cairoRegion = cairo_region_create();
172 GdkDrawingContext* drawingContext
173 = gdk_window_begin_draw_frame( window, cairoRegion );
174 cairo_t* cr = gdk_drawing_context_get_cairo_context( drawingContext );
175 cairo_set_source_rgb (cr, 1, 1, 1); // choisit le blanc.
176 cairo_paint( cr ); // remplit tout dans la couleur choisie.
177
178 // Affiche tous les points en bleu.
179 cairo_set_source_rgb (cr, 0, 0, 1);
180 for ( int i = 0; i < TabParticules_nb( ptrP ); ++i )
181 {
182 drawParticule( pCtxt, cr, TabParticules_get( ptrP, i ) );
183 }
184
185 // On a fini, on peut détruire la structure.
186 gdk_window_end_draw_frame(window,drawingContext);
187 // cleanup
188 cairo_region_destroy(cairoRegion);
189 return TRUE;
190}
void drawParticule(Contexte *pCtxt, cairo_t *cr, Particule p)
Definition main.c:213
Particule TabParticules_get(TabParticules *tab, int i)
Definition particules.c:38

References drawParticule(), SContexte::TabP, TabParticules_get(), and TabParticules_nb().

Referenced by creerIHM().

◆ point2DrawingAreaPoint()

Point point2DrawingAreaPoint ( Contexte pCtxt,
Point  p 
)

Fait la conversion coordonnées réelles de p vers coordonnées de la zone de dessin.

Parameters
pCtxtle contexte de l'IHM
ple point en entrée
Returns
ses coordonnées dans la zone de dessin.

Definition at line 192 of file main.c.

193{
194 Point q;
195 q.x[ 0 ] = ( p.x[ 0 ] + 1.0 ) / 2.0 * pCtxt->width;
196 q.x[ 1 ] = ( 1.0 - p.x[ 1 ] ) / 2.0 * pCtxt->height;
197 return q;
198}

References SContexte::height, SContexte::width, and SPoint::x.

Referenced by drawParticule().

◆ tic()

gint tic ( gpointer  data)

Fonction appelée régulièrement (tous les DT secondes) et qui s'occupe de (presque tout):

Parameters
datacorrespond en fait au pointeur vers le Contexte.

Definition at line 314 of file main.c.

315{
316 Contexte* pCtxt = (Contexte*) data;
317 fontaine( pCtxt, 0.25, -0.5, 0.5, 0.3, 0.3, 2.5 );
318 calculDynamique( pCtxt );
319 deplaceTout( pCtxt );
320 g_timeout_add (1000*DT, tic, (gpointer) pCtxt ); // réenclenche le timer.
321 return 0;
322}
void fontaine(Contexte *pCtxt, double p, double x, double y, double vx, double vy, double m)
Definition main.c:302
void calculDynamique(Contexte *pCtxt)
Definition main.c:346
void deplaceTout(Contexte *pCtxt)
Definition main.c:383

References calculDynamique(), deplaceTout(), DT, fontaine(), and tic().

Referenced by creerIHM(), and tic().

◆ ticAffichage()

gint ticAffichage ( gpointer  data)

Fonction appelée régulièrement (tous les DT_AFF secondes) et qui s'occupe de demander le réaffichage dela zone de dessin.

Parameters
datacorrespond en fait au pointeur vers le Contexte.

Definition at line 324 of file main.c.

325{
326 Contexte* pCtxt = (Contexte*) data;
327 char buffer[ 128 ];
328 sprintf( buffer, "%d points", TabParticules_nb( &pCtxt->TabP ) );
329 gtk_label_set_text( GTK_LABEL( pCtxt->label_nb ), buffer );
330 gtk_widget_queue_draw( pCtxt->drawing_area );
331 g_timeout_add (1000*DT_AFF, ticAffichage, (gpointer) pCtxt ); // réenclenche le timer.
332 return 0;
333}

References SContexte::drawing_area, DT_AFF, SContexte::label_nb, SContexte::TabP, TabParticules_nb(), and ticAffichage().

Referenced by creerIHM(), and ticAffichage().

◆ ticDistance()

gint ticDistance ( gpointer  data)

Fonction appelée régulièrement (tous les secondes) et qui affiche le nombre d'appels à la fonction distance par seconde.

Parameters
datacorrespond en fait au pointeur vers le Contexte.

Definition at line 335 of file main.c.

336{
337 Contexte* pCtxt = (Contexte*) data;
338 char buffer[ 128 ];
339 sprintf( buffer, "%7d nb appels à distance()", getCompteurDistance() ),
340 gtk_label_set_text( GTK_LABEL( pCtxt->label_distance ), buffer );
342 g_timeout_add (1000, ticDistance, (gpointer) pCtxt ); // réenclenche le timer.
343 return 0;
344}
int getCompteurDistance(void)
Definition points.c:64
void resetCompteurDistance(void)
Remet à zéro le compteur du nombre d'appel à distance.
Definition points.c:59

References getCompteurDistance(), SContexte::label_distance, resetCompteurDistance(), and ticDistance().

Referenced by creerIHM(), and ticDistance().