aboutsummaryrefslogtreecommitdiff
path: root/Занимательное программирование/1/1_molecule.c
blob: 35d0d8fb989f7118d4f8eaf4e96365271fb0af24 (plain)
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
107
108
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;
}