diff options
Diffstat (limited to 'Занимательное программирование/1/1_molecule.c')
| -rw-r--r-- | Занимательное программирование/1/1_molecule.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/Занимательное программирование/1/1_molecule.c b/Занимательное программирование/1/1_molecule.c new file mode 100644 index 0000000..35d0d8f --- /dev/null +++ b/Занимательное программирование/1/1_molecule.c @@ -0,0 +1,109 @@ +#include <stdlib.h> +#include <math.h> +#include <gtk/gtk.h> +#include <cairo.h> + +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; +} |
