Программа основана на задачи движения тела брошенного под углом. Сама модель была реализована на языке программирования Си в ОС GNU/Linux на дистрибутиве Ubuntu 9.10 Karmic Koala. Используемый компилятор GCC (GNU Compiler Collection). Сама программа написана в свободной кроcсплатформенной среде разработки Code::Blocks. Так же стоит указать, что рассматриваемое движение материальной точки происходит в идеальных условиях без учёта сопротивления воздуха и других факторов влияющие на полёт. Рассмотрим движение материальной точки, брошенного под углом α к горизонту с начальной скоростью v0. Спроецируем начальную скорость v0 и ускорение a тела на оси X и Y. Проекция начальной скорости на ось X равна Отсюда получается, что положение тела в заданный момент времени определяется системой уравнений: где Вычисления по этой системе производятся в процедуре #include <stdlib.h> #include <gtk/gtk.h> #include <math.h> GtkWidget *edit_angle=NULL,//поле ввода угла *edit_speed=NULL,//поле ввода скорости *edit_metrs=NULL;//поле ввода дистанции double ang, //угол V, //начальная скорость metr,//растояние до мишени t; //время полёта int xe0, ye0;//начальные координаты материальной точки gboolean on_draw (GtkWidget *widget, GdkEventExpose *event){ //Окно GdkGC * gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)]; GdkColor *clr = malloc(sizeof(GdkColor)); gdk_color_parse("black", clr); gdk_gc_set_rgb_fg_color( gc, clr ); gdk_draw_rectangle(widget->window, gc, TRUE, 0, 0, widget->allocation.width, widget->allocation.height); //прямая относительно которой происходит выстрел gdk_color_parse("blue", clr); gdk_gc_set_rgb_fg_color( gc, clr ); gdk_draw_line(widget->window, gc, 0, widget->allocation.height*4/5, widget->allocation.width, widget->allocation.height*4/5); //дуло //находим координаты конца дула xe0=40*cos((M_PI/2-ang*M_PI/180)-M_PI/2); ye0=40*sin((M_PI/2-ang*M_PI/180)-M_PI/2); int ye2=ye0+widget->allocation.height*4/5; gdk_color_parse("red", clr); gdk_gc_set_rgb_fg_color( gc, clr ); gdk_draw_line(widget->window, gc, 0,widget->allocation.height*4/5,xe0,ye2); //мешень gdk_gc_set_rgb_fg_color( gc, clr ); gdk_draw_rectangle(widget->window,gc, TRUE, widget->allocation.width-22, widget->allocation.height*4/5 - 145, 22 , 145); gdk_color_parse("white", clr); gdk_gc_set_rgb_fg_color( gc, clr ); gdk_draw_rectangle(widget->window,gc, TRUE, widget->allocation.width-20, widget->allocation.height*4/5 - 105, 18 , 25); gdk_draw_rectangle(widget->window,gc, TRUE, widget->allocation.width-20, widget->allocation.height*4/5 - 65, 18 , 25); //цифры на мишени GdkScreen *screen = gdk_drawable_get_screen (widget->window); PangoContext *context = gdk_pango_context_get_for_screen (screen); PangoLayout *layout = pango_layout_new (context); pango_layout_set_text (layout, "1", -1); PangoFontDescription *desc = pango_font_description_from_string ("DS Goose 10"); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); pango_layout_set_text(layout, "10", -1); gdk_draw_layout(widget->window, gc, widget->allocation.width-18, widget->allocation.height*4/5 - 135, layout); pango_layout_set_text(layout, "10", -1); gdk_draw_layout(widget->window, gc, widget->allocation.width-18, widget->allocation.height*4/5 - 30, layout); pango_layout_set_text(layout, "50", -1); gdk_draw_layout(widget->window, gc, widget->allocation.width-18, widget->allocation.height*4/5 - 81, layout); gdk_color_parse("black", clr); gdk_gc_set_rgb_fg_color( gc, clr ); pango_layout_set_text(layout, "20", -1); gdk_draw_layout(widget->window, gc, widget->allocation.width-18, widget->allocation.height*4/5 - 102, layout); pango_layout_set_text(layout, "20", -1); gdk_draw_layout(widget->window, gc, widget->allocation.width-18, widget->allocation.height*4/5 - 62, layout); g_object_unref (layout); g_object_unref (context); return TRUE; } gint shut (GtkWidget * widget){ // координаты области рисования int x0e=0; int y0e=0; int x1e=widget->allocation.width; int y1e=widget->allocation.height; //координаты которые ограничат полют мат. точки int yi=widget->allocation.height*4/5; int xi= widget->allocation.width-22; //кооррдинаты реально опбласти float x0r=0; float y0r=-metr; float x1r=metr; float y1r=metr/4; //задаём цвета траектори, мат.тчки GdkGC *line = widget->style->fg_gc[GTK_WIDGET_STATE (widget)]; GdkColor *bullet= malloc(sizeof(GdkColor)); GdkColor *fon = malloc(sizeof(GdkColor)); GdkColor *traectory = malloc(sizeof(GdkColor)); gdk_color_parse("blue", bullet); gdk_color_parse("black", fon); gdk_color_parse("green", traectory); float x, y; int xe, ye, xe2, ye2; //вычисляем координаты положения материальной точки //вычислени реальных координат x=t*V*cos(ang*M_PI/180); y=-(t*V*sin(ang*M_PI/180)-9.8*t*t/2); //отоброжение реальных координат в экраные xe2 = x0e+xe0+(x1e-x0e)/(x1r-x0r)*(x-x0r); ye2 = y0e+ye0+(y1e-y0e)/(y1r-y0r)*(y-y0r)-4; //зарисовка старого положения мат. точки gdk_gc_set_rgb_fg_color( line, fon ); gdk_draw_arc(widget->window, line, TRUE, xe2, ye2, 8, 8, 0, 64 * 360 ); // траектория полёта gdk_gc_set_rgb_fg_color( line, traectory ); gdk_draw_point(widget->window, line, xe2, ye2+=4); t+=0.001; // аналогично вычсляем и рисуем текущее положение мат. точки x=t*V*cos(ang*M_PI/180); y=-(t*V*sin(ang*M_PI/180)-9.8*t*t/2); xe = x0e+xe0+(x1e-x0e)/(x1r-x0r)*(x-x0r); ye = y0e+ye0+(y1e-y0e)/(y1r-y0r)*(y-y0r)-4; gdk_gc_set_rgb_fg_color( line, bullet); gdk_draw_arc(widget->window, line, TRUE, xe, ye, 8, 8, 0, 64 * 360 ); //проверяем на вылет из вычисляемой области if (ye > yi || (xe > xi-5 && ye > widget->allocation.height*4/5 - 135) ) return 0; g_signal_connect (G_OBJECT (widget), "destroy", G_CALLBACK(gtk_main_quit), NULL); return 1; } static void show (){ char *angle_c=NULL, //временая переменя содержащая информацию с поля "угол" *metr_c=NULL, //временая переменя содержащая информацию с поля "расстояние" *speed=NULL; //временая переменя содержащая информацию с поля "скорость" //обрабатываем информацию с полей ввода angle_c = (char*)gtk_entry_get_text(GTK_ENTRY(edit_angle)); ang= atof(angle_c); metr_c = (char*)gtk_entry_get_text(GTK_ENTRY(edit_metrs)); metr= atof(metr_c ); speed = (char*)gtk_entry_get_text(GTK_ENTRY(edit_speed)); V= atof(speed); //окно с моделью выстрела GtkWidget *win1=NULL; win1 = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_resize(GTK_WINDOW(win1), 500, 500); gtk_window_set_position(GTK_WINDOW(win1), GTK_WIN_POS_CENTER); gtk_window_set_title (GTK_WINDOW (win1), "Cтрельба по мишени"); gtk_container_set_border_width (GTK_CONTAINER (win1), 28); t=0;// счётчик времени сброшен g_signal_connect (G_OBJECT (win1), "expose_event", G_CALLBACK (on_draw), NULL); g_timeout_add(4, (GSourceFunc) shut, (gpointer) win1); gtk_widget_show_all(win1); } int main (int argc, char *argv[]){ GtkWidget *window=NULL,//окно для ввода *hbox=NULL,//контейнер хранящий поля ввода, подписи и кнопку *button=NULL, //кнопка *label_angle=NULL,// подпись для угла *label_speed=NULL,//подпись для начальной скорости *label_metrs=NULL;//подпись для растояния до мишени gtk_init(&argc, &argv); //окно полей ввода window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_resize(GTK_WINDOW(window), 300, 100); gtk_window_set_resizable(GTK_WINDOW(window), FALSE); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_title (GTK_WINDOW (window), "Входные даные:"); gtk_container_set_border_width (GTK_CONTAINER (window), 20); //кнопка button = gtk_button_new_with_label (("ОГОНЬ")); //поля ввода edit_angle=gtk_entry_new(); edit_speed=gtk_entry_new(); edit_metrs=gtk_entry_new(); //метки label_angle = gtk_label_new ("Угол от 0 до 90(градусов)"); label_speed = gtk_label_new ("Скорость (м/c)"); label_metrs = gtk_label_new ("Расстояние (м)"); //"контейнер" содержащий объекты hbox = gtk_vbox_new(FALSE, 9); gtk_container_add(GTK_CONTAINER (window), hbox); //---------------------------------------------------------- gtk_container_add(GTK_CONTAINER (hbox), label_angle); gtk_container_add(GTK_CONTAINER (hbox), edit_angle); gtk_container_add(GTK_CONTAINER (hbox), label_speed); gtk_container_add(GTK_CONTAINER (hbox), edit_speed); gtk_container_add(GTK_CONTAINER (hbox), label_metrs); gtk_container_add(GTK_CONTAINER (hbox), edit_metrs); gtk_container_add(GTK_CONTAINER (hbox), button); //при нажатии кнопки g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (show), NULL); g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(window); gtk_main(); return 0; }
Ключевые слова:
модель полёта материальной точки стрельба
|
|||