#include #include #include #include struct molecule { guint x, y, Vx, Vy; } rand_molecule; static const gushort R = 10; static const gushort V = 5; static guint w_width = 850; static guint w_height = 550; static gboolean on_draw_event (GtkWidget *widget, cairo_t *cr, gpointer user_data) { cr = gdk_cairo_create (gtk_widget_get_window (widget)); // Paint a circle cairo_set_source_rgb (cr, 1, 1, 1); cairo_paint (cr); cairo_arc (cr, rand_molecule.x, rand_molecule.y, R, 0, 2 * G_PI); cairo_set_source_rgb (cr, 0, 0, 0); cairo_set_line_width (cr, 1); cairo_stroke (cr); // Free memory cairo_destroy (cr); return FALSE; } static gboolean source_func (gpointer user_data) { cairo_t *cr; cr = gdk_cairo_create (gtk_widget_get_window (user_data)); // Move the molecule rand_molecule.x += rand_molecule.Vx; rand_molecule.y += rand_molecule.Vy; if (rand_molecule.x > (w_width - R)) { rand_molecule.x = w_width - R; rand_molecule.Vx = -rand_molecule.Vx; } if (rand_molecule.x < R) { rand_molecule.x = R; rand_molecule.Vx = -rand_molecule.Vx; } if (rand_molecule.y > (w_height - R)) { rand_molecule.y = w_height - R; rand_molecule.Vy = -rand_molecule.Vy; } if (rand_molecule.y < R) { rand_molecule.y = R; rand_molecule.Vy = -rand_molecule.Vy; } // Paint a circle cairo_set_source_rgb (cr, 1, 1, 1); cairo_paint (cr); cairo_arc (cr, rand_molecule.x, rand_molecule.y, R, 0, 2 * G_PI); cairo_set_source_rgb (cr, 0, 0, 0); cairo_set_line_width (cr, 1); cairo_stroke (cr); // Free memory cairo_destroy (cr); return TRUE; } int main (int argc, char **argv) { double angle; GRand *rand; GtkWindow *window; GtkDrawingArea *darea; // Init gtk_init (&argc, &argv); rand = g_rand_new (); // Get random coordinates for the first molecule rand_molecule.x = g_rand_int_range (rand, R, w_width - R); rand_molecule.y = g_rand_int_range (rand, R, w_height - R); angle = g_rand_double_range (rand, 0, 360) * G_PI / 180; // Get the velocity components rand_molecule.Vx = round (V * sin (angle)); rand_molecule.Vy = round (V * cos (angle)); // Create and configure the window and the needed areas window = (GtkWindow *)gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_position (window, GTK_WIN_POS_CENTER); gtk_window_set_default_size (window, w_width, w_height); gtk_window_set_title (window, "Молекула газа в закрытом сосуде"); darea = (GtkDrawingArea *)gtk_drawing_area_new (); gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (darea)); gtk_widget_show_all (GTK_WIDGET (window)); g_signal_connect (G_OBJECT (darea), "draw", G_CALLBACK (on_draw_event), NULL); g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); g_timeout_add (15, source_func, window); gtk_main (); g_rand_free (rand); return EXIT_SUCCESS; }