From: Rafał Długołęcki Date: Sun, 9 Feb 2014 16:02:11 +0000 (+0100) Subject: Partialy calculating objects positions in the 3D space. X-Git-Url: https://git.dlugolecki.net.pl/?a=commitdiff_plain;h=refs%2Fheads%2F0.3;p=familia.git Partialy calculating objects positions in the 3D space. --- diff --git a/src/dialogs/openfile_dialog.c b/src/dialogs/openfile_dialog.c index 91af946..a91a4fb 100644 --- a/src/dialogs/openfile_dialog.c +++ b/src/dialogs/openfile_dialog.c @@ -4,9 +4,12 @@ #include "../../config.h" #include "openfile_dialog.h" +#include "../storage/storage.h" #include "../i18n.h" +extern GtkDrawingArea * drawing_area; + void openfile_dialog() { GtkFileChooserDialog *dialog; char *filename = NULL; @@ -29,7 +32,12 @@ void openfile_dialog() { result = gedcom_parse_file(filename); + /* File is parsed, so we can calculate positions for loaded users. */ + familia_storage_calc_positions(familia_storage_get_current()); + g_free (filename); + + gtk_widget_queue_draw(GTK_WIDGET(drawing_area)); } gtk_widget_destroy(GTK_WIDGET(dialog)); diff --git a/src/math/camera.c b/src/math/camera.c index 7007524..9682f06 100644 --- a/src/math/camera.c +++ b/src/math/camera.c @@ -1,15 +1,53 @@ #include +#include +#include +#include "camera.h" #include "../storage/storage.h" +#include "../storage/positions.h" -GLdouble camera_pos_x = 0; -GLdouble camera_pos_y = 0; -GLdouble camera_pos_z = 0; +struct position * _cam_pos = NULL; -/** - * - */ -struct position * camera_position_reset() +void camera_position_reset() { - /**/ + if (!_cam_pos) { + _cam_pos = (struct position *)malloc(sizeof(struct position)); + } + familia_position_center(_cam_pos); +} + +void camera_position_free() +{ + if (_cam_pos) { + free(_cam_pos); + _cam_pos = NULL; + } +} + +void camera_mv_h(float x) +{ + assert(_cam_pos != NULL); + + _cam_pos->x = x; +} + +void camera_mv_v(float y) +{ + assert(_cam_pos != NULL); + + _cam_pos->y = y; +} + +struct position * camera_get_position() +{ + if (_cam_pos == NULL) { + camera_position_reset(); + } + return _cam_pos; +} + +void camera_position_dump() +{ + struct position * pos = camera_get_position(); + fprintf(stderr, "Camera: pos(%f, %f, %f)\n", pos->x, pos->y, pos->z); } \ No newline at end of file diff --git a/src/math/camera.h b/src/math/camera.h new file mode 100644 index 0000000..a844acc --- /dev/null +++ b/src/math/camera.h @@ -0,0 +1,73 @@ +/**************************************************************************** + * Familia Lignum - Genealogical program * + * Copyright (C) 2011-2012 Rafał Długołęcki * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; version 2 of the License. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * + * * + ****************************************************************************/ + +#ifndef _FAMILIA_MATH_CAMERA_H +#define _FAMILIA_MATH_CAMERA_H + +#include "3d.h" + +/** + * @file camera.h + * @brief Functions for manipulating the camera. + */ + +/** + * Calculates position of the camera and sets it as the current position. + * You have to invoke this function before any other, related to camera. + */ +void camera_position_reset(); + +/** + * Free's memory related to the camera. + */ +void camera_position_free(); + +/** + * Moves camera horizontally. + * + * Given parameter is absolute value on X axis. It means, that if current camera + * position is: (2,2,2), invoking this function with x=10, results in: (10,2,2) + * + * @param x New camera position on X axis + */ +void camera_mv_h(float x); + +/** + * Moves camera vertically. + * + * Given parameter is absolute value on Y axis. It means, that if current camera + * position is: (2,2,2), invoking this function with y=10, results in: (2,10,2) + * + * @param y New camera position on Y axis + */ +void camera_mv_v(float y); + +/** + * Returns current position of the camera. + * + * @return global position of the camera + */ +struct position * camera_get_position(); + +/** + * Dumps informations on current status of the camera. + */ +void camera_position_dump(); + +#endif /* _FAMILIA_MATH_CAMERA_H */ diff --git a/src/math/positions.c b/src/math/positions.c index bf6b606..fe9068f 100644 --- a/src/math/positions.c +++ b/src/math/positions.c @@ -1,10 +1,13 @@ #include #include +#include #include "positions.h" #include "yearline.h" -#include "storage/individual.h" -#include "storage/family.h" +#include "../storage/individual.h" +#include "../storage/family.h" +#include "../storage/positions.h" +#include "../storage/storage.h" #include "../debug.h" @@ -17,10 +20,18 @@ struct position * calculate_individual_position(struct familia_individual * indi unsigned int children_no = 1; int nth = 0; + assert(individual != NULL); + + pos = (struct position *)malloc(sizeof(struct position)); + pos->x = 0; + pos->y = 0; + pos->z = 0; + parents = familia_individual_get_parents(individual); if (parents == NULL) { + fprintf(stderr, "No parents found, guess correct position (%f,%f,%f)\n", pos->x, pos->y, pos->z); debug("TODO: Calculate position for root individual."); - return NULL; + return pos; } nth = familia_individual_nth_child_of_family(individual, parents); @@ -37,11 +48,6 @@ struct position * calculate_individual_position(struct familia_individual * indi return NULL; } - pos = (struct position *)malloc(sizeof(struct position)); - pos->x = 0; - pos->y = 0; - pos->z = 0; - /* If there is only one child in family, place it vertically * over the family (do not change x and z). For all other * calculate these positions. @@ -54,9 +60,9 @@ struct position * calculate_individual_position(struct familia_individual * indi theta = FAMILY_AVAIL_RANGE / children_no; /* We subtract from FAMILY_AVAIL_RANGE (e.g. 180), - * to count angle from left instead of from right. - * This makes oldest children display in this order. - */ + * to count angle from left instead of from right. + * This makes oldest children display in this order. + */ alpha = FAMILY_AVAIL_RANGE - theta * nth; pos->x = cos(alpha); @@ -64,7 +70,16 @@ struct position * calculate_individual_position(struct familia_individual * indi } /* pos.y is a local coordinate now. */ - pos->y = convert_date_to_height(NULL); + if (individual->birth) { + float average = 0; + average = familia_storage_get_individual_avr_yr(familia_storage_get_current()); + + pos->y = convert_date_to_height(individual->birth) - average; + } + else { + debug("birth == NULL, set y=yr_avg => return pos->y=0"); + pos->y = 0; + } return pos; } diff --git a/src/math/yearline.c b/src/math/yearline.c index 6ab691a..fb6d1c0 100644 --- a/src/math/yearline.c +++ b/src/math/yearline.c @@ -1,4 +1,5 @@ #include "yearline.h" +#include "../storage/positions.h" int convert_date_to_height(struct date_value *dv) { diff --git a/src/storage/individual.c b/src/storage/individual.c index f5a94df..b95764d 100644 --- a/src/storage/individual.c +++ b/src/storage/individual.c @@ -1,5 +1,6 @@ #include #include +#include #include "individual.h" @@ -30,6 +31,8 @@ void familia_individual_free(struct familia_individual * individual) { unsigned int i = 0; + assert(individual != NULL); + if (individual->first_name) { free(individual->first_name); individual->first_name = NULL; @@ -64,6 +67,8 @@ void familia_individual_free(struct familia_individual * individual) void familia_individual_set_first_name(struct familia_individual * individual, char * first_name) { + assert(individual != NULL); + /* Remove old data if it exists */ if (individual->first_name) { free(individual->first_name); @@ -85,11 +90,15 @@ void familia_individual_set_first_name(struct familia_individual * individual, c char * familia_individual_get_first_name(struct familia_individual * individual) { + assert(individual != NULL); + return individual->first_name; } void familia_individual_set_last_name(struct familia_individual * individual, char * last_name) { + assert(individual != NULL); + /* Remove old data if it exists */ if (individual->last_name) { free(individual->last_name); @@ -115,14 +124,20 @@ void familia_individual_set_last_name(struct familia_individual * individual, ch char * familia_individual_get_last_name(struct familia_individual * individual) { + assert(individual != NULL); + return individual->last_name; } void familia_individual_add_family(struct familia_individual * individual, struct familia_family * family) { struct familia_family ** tmp = NULL; - int size = (individual->families_no + 1); + int size = 0; + assert(individual != NULL); + assert(family != NULL); + + size = (individual->families_no + 1); tmp = realloc(individual->families, size * sizeof(struct familia_family *)); if (tmp) { @@ -138,6 +153,8 @@ void familia_individual_add_family(struct familia_individual * individual, struc struct familia_family * familia_individual_get_family_by_id(struct familia_individual * individual, unsigned int id) { + assert(individual != NULL); + if (individual->families_no < id) { debug("Trying to get not existing family!\n"); return NULL; @@ -151,6 +168,8 @@ void familia_individual_remove_family_by_id(struct familia_individual * individu int found = 0; struct familia_family ** tmp = NULL; + assert(individual != NULL); + if (individual->families_no < id) { debug("Trying to remove not existing family!\n"); return; @@ -184,25 +203,33 @@ void familia_individual_remove_family_by_id(struct familia_individual * individu void familia_individual_set_parents(struct familia_individual * individual, struct familia_family * family) { + assert(individual != NULL); + individual->parents = family; } struct familia_family * familia_individual_get_parents(struct familia_individual * individual) { + assert(individual != NULL); + return individual->parents; } void familia_individual_remove_parents(struct familia_individual * individual) { + assert(individual != NULL); + individual->parents = NULL; } int familia_individual_nth_child_of_family(struct familia_individual * individual, struct familia_family * family) { unsigned int i; - unsigned int children_no = family->children_no; - for (i = 0; i < children_no; i++) { + assert(individual != NULL); + assert(family != NULL); + + for (i = 0; i < family->children_no; i++) { if (family->children[i]->id == individual->id) { return i; } @@ -213,6 +240,8 @@ int familia_individual_nth_child_of_family(struct familia_individual * individua void familia_individual_set_birth_date(struct familia_individual * individual, struct date_value dv) { + assert(individual != NULL); + /* TODO: Add multiple birth dates (in case there are many different sources) */ if (!individual->birth) { struct date_value * date = NULL; @@ -225,4 +254,11 @@ void familia_individual_set_birth_date(struct familia_individual * individual, s else { fprintf(stderr, "> Date has been already set, ignoring new one: %s\n", gedcom_date_to_string(&dv)); } +} + +int familia_individual_get_birth_year(struct familia_individual * individual) +{ + assert(individual != NULL); + + return individual->birth->date1.year; } \ No newline at end of file diff --git a/src/storage/individual.h b/src/storage/individual.h index 745698b..abb9a80 100644 --- a/src/storage/individual.h +++ b/src/storage/individual.h @@ -166,4 +166,6 @@ int familia_individual_nth_child_of_family(struct familia_individual * individua */ void familia_individual_set_birth_date(struct familia_individual * individual, struct date_value dv); +int familia_individual_get_birth_year(struct familia_individual * individual); + #endif /*_FAMILIA_INDIVIDUAL_H */ diff --git a/src/storage/positions.c b/src/storage/positions.c index 8cb8ebe..44da39b 100644 --- a/src/storage/positions.c +++ b/src/storage/positions.c @@ -24,6 +24,7 @@ #include "../debug.h" #include "positions.h" +#include "storage.h" /** * Structure holding individual and position pair @@ -59,7 +60,7 @@ struct familia_storage_positions { * * Example graphic object is an individual or family... */ -struct familia_storage_positions * storage_positions; +struct familia_storage_positions * storage_positions = NULL; /** * Initializes storage for individual and family positions. @@ -68,12 +69,14 @@ void _familia_storage_positions_init() { if (!storage_positions) { storage_positions = malloc(sizeof(struct familia_storage_positions)); - + if (!storage_positions) { debug("["__FILE__ "] There was a problem with allocating memory for storage of positions.\n"); } else { + storage_positions->individuals = NULL; storage_positions->individuals_no = 0; + storage_positions->families = NULL; storage_positions->families_no = 0; } } @@ -85,12 +88,22 @@ void _familia_storage_positions_init() void _familia_storage_positions_free() { if (storage_positions) { + unsigned int i; + if (storage_positions->individuals) { + for (i = 0; i < storage_positions->individuals_no; i++) { + free(storage_positions->individuals[i]); + } free(storage_positions->individuals); + storage_positions->individuals_no = 0; } if (storage_positions->families) { + for (i = 0; i < storage_positions->families_no; i++) { + free(storage_positions->families[i]); + } free(storage_positions->families); + storage_positions->families_no = 0; } free(storage_positions); @@ -109,20 +122,36 @@ void _familia_storage_positions_free() void _familia_positions_add_individual_position(struct familia_individual *individual, struct position *pos) { struct familia_storage_individual_position ** tmp = NULL; + struct familia_storage_individual_position * ind_pos = NULL; unsigned int alloc_size = sizeof(struct familia_storage_individual_position *); - int size = (storage_positions->individuals_no + 1); + int size = 0; + + assert(storage_positions != NULL); + + size = (storage_positions->individuals_no + 1); + + ind_pos = malloc(sizeof(struct familia_storage_individual_position)); + + if (!ind_pos) { + debug("There was a problem with allocating memory for individual<->position pair"); + return; + } tmp = realloc(storage_positions->individuals, size * alloc_size); if (tmp) { storage_positions->individuals = tmp; - storage_positions->individuals[storage_positions->individuals_no]->ind = individual; - storage_positions->individuals[storage_positions->individuals_no]->pos = pos; + + ind_pos->ind = individual; + ind_pos->pos = pos; + + storage_positions->individuals[storage_positions->individuals_no] = ind_pos; storage_positions->individuals_no++; } else { debug("There were problems with allocating memory for storage of individual positions->\n"); + free(ind_pos); } } @@ -183,13 +212,8 @@ struct position * familia_position_get_individual_position(struct familia_indivi unsigned int i; unsigned int id; - /* - * Uninitialized global. Return error. - */ - if (!storage_positions || !storage_positions->individuals) { - debug("Trying to request individual position, but positions storage is not initialized.\n"); - return NULL; - } + assert(storage_positions != NULL); + assert(storage_positions->individuals != NULL); id = individual->id; @@ -210,13 +234,8 @@ struct position * familia_position_get_family_position(struct familia_family *fa unsigned int i; unsigned int id; - /* - * Uninitialized global. Return error. - */ - if (!storage_positions || !storage_positions->families) { - debug("Trying to request family position, but positions storage is not initialized.\n"); - return NULL; - } + assert(storage_positions != NULL); + assert(storage_positions->families != NULL); id = family->id; @@ -230,4 +249,13 @@ struct position * familia_position_get_family_position(struct familia_family *fa * Entry not found for a given individual. Return error. */ return NULL; +} + +void familia_position_center(struct position * pos) +{ + assert(pos != NULL); + + pos->x = 0; + pos->y = 0; + pos->z = 0; } \ No newline at end of file diff --git a/src/storage/positions.h b/src/storage/positions.h index 6f96b90..c5b9dc5 100644 --- a/src/storage/positions.h +++ b/src/storage/positions.h @@ -59,4 +59,6 @@ struct position * familia_position_get_individual_position(struct familia_indivi */ struct position * familia_position_get_family_position(struct familia_family *family); +void familia_position_center(struct position * pos); + #endif /* _FAMILIA_STORAGE_POSITIONS_H */ diff --git a/src/storage/storage.c b/src/storage/storage.c index c54e6a0..834bb0a 100644 --- a/src/storage/storage.c +++ b/src/storage/storage.c @@ -1,14 +1,19 @@ #include #include +#include #include "storage.h" +#include "positions.h" #include "../debug.h" struct familia_storage * _familia_storage_current; +extern struct familia_storage_positions * storage_positions; extern void _familia_storage_positions_init(); extern void _familia_storage_positions_free(); +extern void _familia_positions_add_individual_position(struct familia_individual *individual, struct position *pos); +extern void _familia_positions_add_family_position(struct familia_family *family, struct position *pos); struct familia_storage * familia_storage_get_current() { @@ -35,7 +40,7 @@ struct familia_storage * familia_storage_new() storage->families = NULL; storage->families_no = 0; -/* _familia_storage_positions_init();*/ + _familia_storage_positions_init(); return storage; } @@ -64,7 +69,7 @@ void familia_storage_free(struct familia_storage * storage) storage->families_no = 0; } -/* _familia_storage_positions_free();*/ + _familia_storage_positions_free(); } void familia_storage_add_individual(struct familia_storage * storage, struct familia_individual * individual) @@ -201,6 +206,49 @@ void familia_storage_remove_family_by_id(struct familia_storage * storage, unsig } } +float familia_storage_get_individual_avr_yr(struct familia_storage * storage) { + float result = 0; + float average = 0; + unsigned int average_no = 0; + unsigned int i; + struct familia_individual * individual = NULL; + + assert(storage != NULL); + + for (i = 0; i < storage->individuals_no; i++) { + individual = storage->individuals[i]; + + if (individual->birth != NULL) { + int year = familia_individual_get_birth_year(individual); + average += year; + average_no++; + } + } + + if (average_no > 0) { + result = (float)average / (float)average_no; + } + + return result; +} +void familia_storage_calc_positions(struct familia_storage * storage) +{ + unsigned int i; + struct position * pos = NULL; + struct familia_individual * individual = NULL; + + assert(storage != NULL); + + debug("Calculating positions"); + for (i = 0; i < storage->individuals_no; i++) { + individual = storage->individuals[i]; + pos = calculate_individual_position(individual); + fprintf(stderr, "CalcPos: (%f, %f. %f)\n", pos->x, pos->y, pos->z); + _familia_positions_add_individual_position(individual, pos); + } + debug("All positions has been calculated"); +} + void familia_storage_dump_all() { unsigned int i; @@ -274,4 +322,4 @@ void familia_storage_dump_all() } } } -} +} \ No newline at end of file diff --git a/src/storage/storage.h b/src/storage/storage.h index b72121b..9997976 100644 --- a/src/storage/storage.h +++ b/src/storage/storage.h @@ -22,6 +22,7 @@ #include "individual.h" #include "family.h" +#include "positions.h" /** * @file storage.h @@ -129,6 +130,10 @@ struct familia_family * familia_storage_get_family_by_id(struct familia_storage */ void familia_storage_remove_family_by_id(struct familia_storage * storage, unsigned int id); +float familia_storage_get_individual_avr_yr(struct familia_storage * storage); + +void familia_storage_calc_positions(struct familia_storage * storage); + void familia_storage_dump_all(); #endif /*_FAMILIA_STORAGE_H */ diff --git a/src/ui/drawing_area.c b/src/ui/drawing_area.c index ee915e9..0eefa39 100644 --- a/src/ui/drawing_area.c +++ b/src/ui/drawing_area.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,14 +6,13 @@ #include "../debug.h" #include "drawing_area.h" +#include "../math/3d.h" +#include "../math/camera.h" #include "../graphics/constants.h" #include "../graphics/individual.h" #include "../graphics/family.h" #include "../storage/storage.h" - -extern GLdouble camera_pos_x; -extern GLdouble camera_pos_y; -extern GLdouble camera_pos_z; +#include "../storage/positions.h" GtkDrawingArea * drawing_area = NULL; @@ -26,33 +26,52 @@ gboolean drawing_area_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data) unsigned int i; unsigned int individuals_no; unsigned int families_no; + float x, z; + float avr_ind_yr = 0; + struct position * pos = NULL; + struct position * cam_pos = NULL; + struct familia_individual * individual = NULL; + struct familia_storage * storage = NULL; /*** OpenGL BEGIN ***/ if (!gtk_widget_begin_gl (widget)) { return FALSE; } + cam_pos = camera_get_position(); + storage = familia_storage_get_current(); + glMatrixMode (GL_MODELVIEW); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity (); - gluLookAt (camera_pos_x, camera_pos_y, camera_pos_z, 0.0, 0.0, -100.0, 0.0, 1.0, 0.0); + /*Z+10, because we want to move camera backwards, to see rendered objects. */ + gluLookAt (cam_pos->x, cam_pos->y, cam_pos->z + 10, 0.0, 0.0, -100.0, 0.0, 1.0, 0.0); + camera_position_dump(); - individuals_no = familia_storage_get_current()->individuals_no; + individuals_no = storage->individuals_no; for (i = 0; i < individuals_no; i++) { + individual = familia_storage_get_individual_by_id(storage, i); + pos = calculate_individual_position(individual); + pos->x *= (GR_IND_RADIUS + 1)*10; + /* TODO: For now many individuals without birth date, or root ones will be positioned on (0,0,0). Fix algorithm.. */ + /* + fprintf(stderr, "ind(%d) calc-pos: x:%f, z:%f\n", i, pos->x, pos->z); + fprintf(stderr, "ind(%d) hard-pos: x:%f, z:%f\n", i, x, z); + */ glPushMatrix (); - glTranslatef(i * (GR_IND_RADIUS + 1), 0, -10); + glTranslatef(pos->x, pos->y, pos->z); glColor3f (1.0, 1.0, 1.0); graphics_render_individual(); glPopMatrix (); } - families_no = familia_storage_get_current()->families_no; + families_no = storage->families_no; for (i = 0; i < families_no; i++) { glPushMatrix (); - glTranslatef(i * (GR_FAM_RADIUS + 1), -3, -10); + glTranslatef(i * (GR_FAM_RADIUS + 1), -3, 0); glColor3f (1.0, 1.0, 1.0); graphics_render_family(); glPopMatrix (); @@ -119,6 +138,8 @@ void drawing_area_realize (GtkWidget *widget, gpointer data) glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_FLAT); + camera_position_reset(); + gtk_widget_end_gl (widget, FALSE); /*** OpenGL END ***/ @@ -131,5 +152,5 @@ void drawing_area_realize (GtkWidget *widget, gpointer data) */ void drawing_area_unrealize (GtkWidget *widget, gpointer data) { - /* Code */ + camera_position_free(); } diff --git a/src/ui/scrollbars.c b/src/ui/scrollbars.c index 96e946f..42a31fc 100644 --- a/src/ui/scrollbars.c +++ b/src/ui/scrollbars.c @@ -1,12 +1,9 @@ #include #include +#include "../math/camera.h" #include "scrollbars.h" -extern GLdouble camera_pos_x; -extern GLdouble camera_pos_y; -extern GLdouble camera_pos_z; - extern GtkDrawingArea * drawing_area; void horizontal_scrollbar_changed (GtkAdjustment *adjustment, gpointer user_data) @@ -16,9 +13,10 @@ void horizontal_scrollbar_changed (GtkAdjustment *adjustment, gpointer user_data void horizontal_scrollbar_value_changed (GtkAdjustment *adjustment, gpointer user_data) { - //gdk_window_invalidate_rect(gtk_widget_get_window (adjustment), NULL, TRUE); - camera_pos_x = gtk_adjustment_get_value(adjustment); - fprintf (stderr, "HS_value_changed, camera_pos_x: %f\n", camera_pos_x); + float x = gtk_adjustment_get_value(adjustment); + + camera_mv_h(x); + fprintf (stderr, "HS_value_changed, camera_pos_x: %f\n", x); gtk_widget_queue_draw(GTK_WIDGET(drawing_area)); } @@ -29,8 +27,9 @@ void vertical_scrollbar_changed (GtkAdjustment *adjustment, gpointer user_data) void vertical_scrollbar_value_changed (GtkAdjustment *adjustment, gpointer user_data) { - //gdk_window_invalidate_rect(gtk_widget_get_window (adjustment), NULL, TRUE); - camera_pos_y = -gtk_adjustment_get_value(adjustment); - fprintf (stderr, "VS_value_changed, camera_pos_y: %f\n", camera_pos_y); + float y = -gtk_adjustment_get_value(adjustment); + + camera_mv_v(y); + fprintf (stderr, "VS_value_changed, camera_pos_y: %f\n", y); gtk_widget_queue_draw(GTK_WIDGET(drawing_area)); } \ No newline at end of file