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
| #include <gtk/gtk.h>
#include <math.h>
#include <cairo.h>
#define WIDTH 640
#define HEIGHT 480
#define ZOOM_X 100.0
#define ZOOM_Y 100.0
gfloat f (gfloat x)
{
return 0.03 * pow (x, 3);
}
static gboolean
on_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
{
cairo_t *cr = gdk_cairo_create (widget->window);
GdkRectangle da; /* Dimensions de la GtkDrawingArea */
gdouble dx = 5.0, dy = 5.0; /* Nombre de pixels entre chaque point calculé */
gdouble i, clip_x1 = 0.0, clip_y1 = 0.0, clip_x2 = 0.0, clip_y2 = 0.0;
gint unused = 0;
/* On définit la zone de clipping, cela correspond à la zone à
* raffraîchir. En ne dessinant que le strict nécessaire, on dessinera
* plus rapidement */
cairo_rectangle (cr,
event->area.x,
event->area.y,
event->area.width,
event->area.height);
cairo_clip (cr);
/* On détermine les dimensions de la GtkDrawingArea */
gdk_window_get_geometry (widget->window,
&da.x,
&da.y,
&da.width,
&da.height,
&unused);
/* On dessine un fond noir */
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
cairo_paint (cr);
/* On change la matrice de transformation. C'est comme un changement
* de repère en mathématiques. On centre d'abord l'origine du repère.
* Ensuite on change son échelle */
cairo_translate (cr, da.width / 2, da.height / 2);
cairo_scale (cr, ZOOM_X, -ZOOM_Y);
/* On détermine les points à calculer (c'est à dire ceux se trouvant
* dans la zone de clipping) */
cairo_device_to_user_distance (cr, &dx, &dy);
cairo_clip_extents (cr, &clip_x1, &clip_y1, &clip_x2, &clip_y2);
cairo_set_line_width (cr, dx);
/* On dessine les axes */
cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
cairo_move_to (cr, clip_x1, 0.0);
cairo_line_to (cr, clip_x2, 0.0);
cairo_move_to (cr, 0.0, clip_y1);
cairo_line_to (cr, 0.0, clip_y2);
cairo_stroke (cr);
/* On rajoute les points de la coube en les reliants par une droite */
for (i = clip_x1; i < clip_x2; i += dx)
cairo_line_to (cr, i, f (i));
/* On dessine la courbe */
cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
cairo_stroke (cr);
cairo_destroy (cr);
return FALSE;
}
int
main (int argc, char **argv)
{
GtkWidget *window;
GtkWidget *da;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size (GTK_WINDOW (window), WIDTH, HEIGHT);
gtk_window_set_title (GTK_WINDOW (window), "Affichage de courbe");
g_signal_connect (G_OBJECT (window), "delete-event", gtk_main_quit, NULL);
da = gtk_drawing_area_new ();
gtk_container_add (GTK_CONTAINER (window), da);
g_signal_connect (G_OBJECT (da),
"expose-event",
G_CALLBACK (on_expose_event),
NULL);
gtk_widget_show_all (window);
gtk_main ();
return 0;
} |