aboutsummaryrefslogtreecommitdiff
path: root/Занимательное программирование/1/1_molecule.c
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2025-12-13 16:35:46 +0100
committerEugen Wissner <belka@caraus.de>2025-12-13 16:35:46 +0100
commitc1147629f7aae2ee90ccd7c9f1ccbf106361d486 (patch)
tree67a549c6796702fa3db9248d599424066345dab4 /Занимательное программирование/1/1_molecule.c
parent98329e0a3dd4f78b5d815ac3896272ec70904901 (diff)
downloadbook-exercises-c1147629f7aae2ee90ccd7c9f1ccbf106361d486.tar.gz
Add book "Занимательное программирование"
Diffstat (limited to 'Занимательное программирование/1/1_molecule.c')
-rw-r--r--Занимательное программирование/1/1_molecule.c109
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;
+}