Add book "Занимательное программирование"
This commit is contained in:
109
Занимательное программирование/1/1_molecule.c
Normal file
109
Занимательное программирование/1/1_molecule.c
Normal file
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user