Задача: отобразить солнечную систему; В этой картинке 9 анимированых объектов, 10 статический и 5 статических полей с информацией: Изменение координат планет происходит при помощи функций sin и cos, делая круговые движения. Координаты планет системы вычисляются по формулам: x[i]=a[i]*cos(t[i])+WIDTH/2; где i - номер планеты по создаваемой базе данных Очевидно что орбиты планет имеют эллиптическую форму, которая зависит от эксцентриситета орбит. Но при попытки использовать масштабирование для создания модели, я столкнулся с невозможностью использования такого метода т.к. размеры некоторых планет во много раз превосходят другие. Поэтому пришлось использовать схематическую модель, базирующаяся на реальных характеристиках планет и их орбит. Скорость движения планет вычисляется относительно их реальных скоростей, уменьшив их в 1000 раз. //Необходимые строки для подключения gtk в VS #pragma comment(lib,"gthread-2.0.lib") #pragma comment(lib,"gtk-win32-2.0.lib") #pragma comment(lib,"glib-2.0.lib") #pragma comment(lib,"gobject-2.0.lib") #pragma comment(lib,"gdk-win32-2.0.lib") #pragma comment(lib,"gdk_pixbuf-2.0.lib") #pragma comment(lib,"pango-1.0.lib") #pragma comment(lib,"pangowin32-1.0.lib") #pragma comment(lib,"intl.lib") #include <gtk/gtk.h> #include <math.h>//для вычисления синусов и косинусов #include <stdlib.h> //Размеры окна #define WIDTH 1000 #define HEIGHT 700 #define M_PI 3.14 #define OTSTUP 10 #define lim_planet 9 #define lim_name 15 #define interval 25//Интервал вызова ф-ии рисования солнечной системы #define speed_change_t 0.001 //На сколько изменяется параметр t char name[lim_planet][lim_name],change_num[50],type_name[lim_planet][2*lim_name],ch_num[lim_planet]; float e[lim_planet],r_e[lim_planet],t[9],k,v[lim_planet],r_v[lim_planet]; int d[lim_planet],r_d[lim_planet],a[lim_planet],r_a[lim_planet],b[lim_planet],x[lim_planet],y[lim_planet],i,me=77777,xs=5,ys=20; int timer[lim_planet],xt[lim_planet],yt[lim_planet],num_change_t[lim_planet]; FILE *info=fopen("other_information.txt","rt");//файл с используемыми характеристиками планет FILE *r_info=fopen("information.txt","rt");//файл с реальными характеристиками планет GdkColor fclrs,bclr,clr; GdkGC *gc; gboolean destroy(GtkWidget *widget); gint delete_event(GtkWidget *widget); gboolean information(GtkWidget *widget);//ф-ия создавания полей с информацией о планетах gboolean run_planet(GtkWidget *widget);//ф-ия рисования слнечной системы int main(int arge, char **argv) { xt[0]=0;yt[0]=240; for(i=1;i<lim_planet;i++) {yt[i]=yt[i-1]+33;xt[i]=0;} //Создание базы с информацией for(i=0;i<5;i++) {fscanf(r_info,"%s",type_name[i]);} for(i=0;i<lim_planet;i++) { fscanf(r_info,"%f",&r_e[i]); fscanf(r_info,"%d",&r_a[i]); fscanf(r_info,"%d",&r_d[i]); fscanf(r_info,"%f",&r_v[i]); }fclose(r_info); for(i=0;i<lim_planet;i++) { fscanf(info,"%s",name[i]); fscanf(info,"%f",&e[i]); fscanf(info,"%d",&a[i]); fscanf(info,"%d",&d[i]); fscanf(info,"%f",&v[i]); }fclose(info); //Увеличение эксцентриситета планет для зрелещности изображения for(i=0;i<lim_planet;i++) e[i]*=1.2; //Вычисление максимального значения оси относительно экрана b[8]=HEIGHT/2-OTSTUP; //k=b(плутона максимальное компьютерное)/b(плутона реальное) k=b[8]/(a[8]*sqrt(1-(e[8]*e[8]))); //Уменьшение значений полуосей и диаметров планет согласно экрана и масштабирования for(i=0;i<lim_planet;i++) { a[i]*=k; b[i]=a[i]*sqrt(1-e[i]*e[i]); d[i]/=200; } gtk_init(&arge,&argv); GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request(window,WIDTH,HEIGHT); g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(destroy),NULL); g_signal_connect(G_OBJECT(window),"delete_event",G_CALLBACK(delete_event),NULL); gdk_color_parse("black",&clr); gtk_widget_modify_bg(window,GTK_STATE_NORMAL,&clr); g_signal_connect(G_OBJECT(window),"expose_event",G_CALLBACK(run_planet),NULL); g_timeout_add(interval,(GSourceFunc)run_planet,(gpointer)window); g_timeout_add(interval,(GSourceFunc)information,(gpointer)window); gtk_widget_show_all(window); gtk_main(); return 0; } gboolean destroy(GtkWidget *widget) { return FALSE; } gint delete_event(GtkWidget *widget) { gtk_main_quit(); return 1; } gboolean information(GtkWidget *widget) { gc = widget->style->fg_gc[GTK_WIDGET_STATE(widget)]; GdkFont *font=gdk_fontset_load("Lucida Console"); for(i=0;i<lim_planet;i++) { gdk_gc_set_rgb_fg_color(gc,&clr); sprintf(ch_num,"%d",timer[i]); gdk_draw_string(widget->window,font,gc,xt[i],yt[i],ch_num); //проверка на изменение времени на планете, если число изменений(вычесленных в ручную) совпадает с данным числом, то год прошёл switch(i) { case 0: { if(num_change_t[0]==131) { num_change_t[0]=0; timer[0]++; }break; } case 1: { if(num_change_t[1]==179) { num_change_t[1]=0; timer[1]++; }break; } case 2: { if(num_change_t[2]==210) { num_change_t[2]=0; timer[2]++; }break; } case 3: { if(num_change_t[3]==261) { num_change_t[3]=0; timer[3]++; }break; } case 4: { if(num_change_t[4]==479) { num_change_t[4]=0; timer[4]++; }break; } case 5: { if(num_change_t[5]==654) { num_change_t[5]=0; timer[5]++; }break; } case 6: { if(num_change_t[6]==924) { num_change_t[6]=0; timer[6]++; }break; } case 7: { if(num_change_t[7]==1162) { num_change_t[7]=0; timer[7]++; }break; } case 8: { if(num_change_t[8]==1281) { num_change_t[8]=0; timer[8]++; }break; } } //Создание поля с годами на планетах fclrs.pixel = 0; fclrs.red = 0; fclrs.green = 0; fclrs.blue = 0xFFFF; gdk_gc_set_rgb_fg_color(gc,&fclrs); gdk_draw_string(widget->window,font,gc,xt[i],yt[i]-20,"Years "); gdk_draw_string(widget->window,font,gc,xt[i]+70,yt[i]-20,name[i]); sprintf(ch_num,"%d",timer[i]); fclrs.pixel = 0; fclrs.red = 0xFFFF; fclrs.green = 0; fclrs.blue = 0; gdk_gc_set_rgb_fg_color(gc,&fclrs); gdk_draw_string(widget->window,font,gc,xt[i],yt[i],ch_num); } //создание лэйбочки с информацией о хозяине проекта fclrs.pixel = 0; fclrs.red = 0; fclrs.green = 0xFFFF; fclrs.blue = 0; gdk_gc_set_rgb_fg_color(gc,&fclrs); gdk_draw_line(widget->window,gc,862,255,997,255); gdk_draw_line(widget->window,gc,862,450,997,450); gdk_draw_line(widget->window,gc,862,255,862,450); gdk_draw_line(widget->window,gc,997,255,997,450); fclrs.pixel = 0;fclrs.red = 0xFA00;fclrs.green = 0xFD00;fclrs.blue = 0;gdk_gc_set_rgb_fg_color(gc,&fclrs); gdk_draw_string(widget->window,font,gc,865,272,"The project"); gdk_draw_string(widget->window,font,gc,865,292,"of the second"); gdk_draw_string(widget->window,font,gc,865,312,"year student"); gdk_draw_string(widget->window,font,gc,865,332,"Groups 201-p"); gdk_draw_string(widget->window,font,gc,865,352,"Specialities"); gdk_draw_string(widget->window,font,gc,865,372,"the applied"); gdk_draw_string(widget->window,font,gc,865,392,"mathematics"); gdk_draw_string(widget->window,font,gc,865,412,"by Kiseris"); gdk_draw_string(widget->window,font,gc,865,432," Arthur"); //Вывод первого поля, к-ое содержит информацию о эксцентриситете планет fclrs.pixel = 0; fclrs.red = 0xFFFF; fclrs.green = 0; fclrs.blue = 0; gdk_gc_set_rgb_fg_color(gc,&fclrs); xs=5;ys=20; gdk_draw_string(widget->window,font,gc,xs,ys,type_name[0]); xs+=80; gdk_draw_string(widget->window,font,gc,xs,ys,type_name[1]); xs=5;ys+=20; fclrs.pixel = 0; fclrs.red = 0; fclrs.green = 0xFFFF; fclrs.blue = 0x00FF; gdk_gc_set_rgb_fg_color(gc,&fclrs); for(i=0,xs=5;i<9;i++,xs=5) { gdk_draw_string(widget->window,font,gc,xs,ys,name[i]); xs+=80; sprintf(change_num, "%3.3f",r_e[i]); gdk_draw_string(widget->window,font,gc,xs,ys,change_num); ys+=20; } //Вывод второго поля, к-ое содержит информацию о среднем расстоянии планет от солнца fclrs.pixel = 0; fclrs.red = 0xFFFF; fclrs.green = 0; fclrs.blue = 0; gdk_gc_set_rgb_fg_color(gc,&fclrs); xs=5;ys=520; gdk_draw_string(widget->window,font,gc,xs,ys,type_name[0]); xs+=80; gdk_draw_string(widget->window,font,gc,xs,ys,type_name[2]); xs=5;ys+=20; fclrs.pixel = 0; fclrs.red = 0; fclrs.green = 0xFFFF; fclrs.blue = 0x00FF; gdk_gc_set_rgb_fg_color(gc,&fclrs); for(i=0,xs=5;i<9;i++,xs=5) { gdk_draw_string(widget->window,font,gc,xs,ys,name[i]); xs+=80; sprintf(change_num, "%d",r_a[i]); gdk_draw_string(widget->window,font,gc,xs,ys,change_num); gdk_draw_string(widget->window,font,gc,xs+45,ys,"mln.km"); ys+=20; } //Вывод третего поля, к-ое содержит информацию о диаметре планет fclrs.pixel = 0; fclrs.red = 0xFFFF; fclrs.green = 0; fclrs.blue = 0; gdk_gc_set_rgb_fg_color(gc,&fclrs); xs=830;ys=20; gdk_draw_string(widget->window,font,gc,xs,ys,type_name[0]); xs+=80; gdk_draw_string(widget->window,font,gc,xs,ys,type_name[3]); xs=830;ys+=20; fclrs.pixel = 0; fclrs.red = 0; fclrs.green = 0xFFFF; fclrs.blue = 0x00FF; gdk_gc_set_rgb_fg_color(gc,&fclrs); for(i=0,xs=830;i<9;i++,xs=830) { gdk_draw_string(widget->window,font,gc,xs,ys,name[i]); xs+=80; sprintf(change_num, "%d",r_d[i]); gdk_draw_string(widget->window,font,gc,xs,ys,change_num); gdk_draw_string(widget->window,font,gc,xs+40,ys," km"); ys+=20; } //Вывод четвёртого поля, к-ое содержит информацию о диаметре планет fclrs.pixel = 0; fclrs.red = 0xFFFF; fclrs.green = 0; fclrs.blue = 0; gdk_gc_set_rgb_fg_color(gc,&fclrs); xs=830;ys=520; gdk_draw_string(widget->window,font,gc,xs,ys,type_name[0]); xs+=80; gdk_draw_string(widget->window,font,gc,xs,ys,type_name[4]); xs=830;ys+=20; fclrs.pixel = 0; fclrs.red = 0; fclrs.green = 0xFFFF; fclrs.blue = 0x00FF; gdk_gc_set_rgb_fg_color(gc,&fclrs); for(i=0,xs=830;i<9;i++,xs=830) { gdk_draw_string(widget->window,font,gc,xs,ys,name[i]); xs+=80; sprintf(change_num, "%3.1f",r_v[i]); gdk_draw_string(widget->window,font,gc,xs,ys,change_num); gdk_draw_string(widget->window,font,gc,xs+40,ys," km/s"); ys+=20; } return TRUE; } gboolean run_planet(GtkWidget *widget) { gc = widget->style->fg_gc[GTK_WIDGET_STATE(widget)]; GdkFont *font=gdk_fontset_load("Lucida Console"); //Стерание предыдущих планет и названия используя цвет фона(чёрный) fclrs.pixel = 0; fclrs.red = 0; fclrs.green = 0; fclrs.blue = 0; gdk_gc_set_rgb_fg_color(gc,&fclrs); gdk_draw_arc(widget->window,gc,TRUE,x[8]-d[8],y[8]-d[8],2*d[8],2*d[8],0,360*64); gdk_draw_string(widget->window,font,gc,x[8]-25,y[8]-10,name[8]); gdk_draw_arc(widget->window,gc,TRUE,x[7]-(d[7]/2),y[7]-(d[7]/2),d[7],d[7],0,360*64); gdk_draw_string(widget->window,font,gc,x[7]-30,y[7]-16,name[7]); gdk_draw_arc(widget->window,gc,TRUE,x[6]-(d[6]/2),y[6]-(d[6]/2),d[6],d[6],0,360*64); gdk_draw_string(widget->window,font,gc,x[6]-20,y[6]-13,name[6]); gdk_draw_arc(widget->window,gc,TRUE,x[5]-(d[5]/2),y[5]-(d[5]/2),d[5],d[5],0,360*64); gdk_draw_rectangle(widget->window,gc,TRUE,x[5]-(d[5]/2)-5,y[5]-3,d[5]+8,3); gdk_draw_string(widget->window,font,gc,x[5]-30,y[5]-20,name[5]); gdk_draw_arc(widget->window,gc,TRUE,x[4]-(d[4]/2),y[4]-(d[4]/2),d[4],d[4],0,360*64); gdk_draw_string(widget->window,font,gc,x[4]-30,y[4]-20,name[4]); gdk_draw_arc(widget->window,gc,TRUE,x[3]-(d[3]/2),y[3]-(d[3]/2),d[3],d[3],0,360*64); gdk_draw_string(widget->window,font,gc,x[3]-20,y[3]-13,name[3]); gdk_draw_arc(widget->window,gc,TRUE,x[2]-(d[2]/2),y[2]-(d[2]/2),d[2],d[2],0,360*64); gdk_draw_string(widget->window,font,gc,x[2]-20,y[2]-13,name[2]); gdk_draw_arc(widget->window,gc,TRUE,x[1]-(d[1]/2),y[1]-(d[1]/2),d[1],d[1],0,360*64); gdk_draw_string(widget->window,font,gc,x[1]-30,y[1]-20,name[1]); gdk_draw_arc(widget->window,gc,TRUE,x[0]-(d[0]/2),y[0]-(d[0]/2),d[0],d[0],0,360*64); gdk_draw_string(widget->window,font,gc,x[0]-30,y[0]-20,name[0]); //Изменение координат for(i=0;i<9;i++) { x[i]=a[i]*cos(t[i])+WIDTH/2; y[i]=b[i]*sin(t[i])+HEIGHT/2; } //Отображение граней для осей СС fclrs.pixel = 0; fclrs.red = 0; fclrs.green = 0xFFFF; fclrs.blue = 0x00FF; gdk_gc_set_rgb_fg_color(gc,&fclrs); for(i=0;i<9;i++) { gdk_draw_arc(widget->window,gc,FALSE,WIDTH/2-a[i],HEIGHT/2-b[i],2*a[i],2*b[i],0,360*64); } //Рисование новых рисунков с новыми координатами fclrs.pixel = 0; fclrs.red = 0; fclrs.green = 0; fclrs.blue = 0xFFFF; gdk_gc_set_rgb_fg_color(gc,&fclrs); gdk_draw_arc(widget->window,gc,TRUE,x[8]-(d[8]/2),y[8]-(d[8]/2),d[8],d[8],0,360*64); fclrs.pixel = 0; fclrs.red = 0x0B00; fclrs.green = 0x2700; fclrs.blue = 0xB500; gdk_gc_set_rgb_fg_color(gc,&fclrs); gdk_draw_arc(widget->window,gc,TRUE,x[7]-(d[7]/2),y[7]-(d[7]/2),d[7],d[7],0,360*64); fclrs.pixel = 0; fclrs.red = 0x7900; fclrs.green = 0x8C00; fclrs.blue = 0xFF00; gdk_gc_set_rgb_fg_color(gc,&fclrs); gdk_draw_arc(widget->window,gc,TRUE,x[6]-(d[6]/2),y[6]-(d[6]/2),d[6],d[6],0,360*64); fclrs.pixel = 0; fclrs.red = 0xFC00; fclrs.green = 0xE400; fclrs.blue = 0xAC00; gdk_gc_set_rgb_fg_color(gc,&fclrs); gdk_draw_arc(widget->window,gc,TRUE,x[5]-(d[5]/2),y[5]-(d[5]/2),d[5],d[5],0,360*64); fclrs.pixel = 0; fclrs.red = 0x8F00; fclrs.green = 0x6500; fclrs.blue = 0x0200; gdk_gc_set_rgb_fg_color(gc,&fclrs); gdk_draw_rectangle(widget->window,gc,TRUE,x[5]-(d[5]/2)-5,y[5]-3,d[5]+8,3); fclrs.pixel = 0; fclrs.red = 0x9700; fclrs.green = 0x8000; fclrs.blue = 0x4900; gdk_gc_set_rgb_fg_color(gc,&fclrs); gdk_draw_arc(widget->window,gc,TRUE,x[4]-(d[4]/2),y[4]-(d[4]/2),d[4],d[4],0,360*64); fclrs.pixel = 0; fclrs.red = 0xDDDD; fclrs.green = 0; fclrs.blue = 0; gdk_gc_set_rgb_fg_color(gc,&fclrs); gdk_draw_arc(widget->window,gc,TRUE,x[3]-(d[3]/2),y[3]-(d[3]/2),d[3],d[3],0,360*64); fclrs.pixel = 0; fclrs.red = 0; fclrs.green = 0xFFFF; fclrs.blue = 0x00DD; gdk_gc_set_rgb_fg_color(gc,&fclrs); gdk_draw_arc(widget->window,gc,TRUE,x[2]-(d[2]/2),y[2]-(d[2]/2),d[2],d[2],0,360*64); fclrs.pixel = 0; fclrs.red = 0xFFFF; fclrs.green = 0xCCCC; fclrs.blue = 0xCCCC; gdk_gc_set_rgb_fg_color(gc,&fclrs); gdk_draw_arc(widget->window,gc,TRUE,x[1]-(d[1]/2),y[1]-(d[1]/2),d[1],d[1],0,360*64); fclrs.pixel = 0; fclrs.red = 0xFFFF; fclrs.green = 0xA5AA; fclrs.blue = 0; gdk_gc_set_rgb_fg_color(gc,&fclrs); gdk_draw_arc(widget->window,gc,TRUE,x[0]-(d[0]/2),y[0]-(d[0]/2),d[0],d[0],0,360*64); //Рисование солнца fclrs.pixel = 0; fclrs.red = 0xFA00; fclrs.green = 0xFD00; fclrs.blue = 0; gdk_gc_set_rgb_fg_color(gc,&fclrs); gdk_draw_arc(widget->window,gc,TRUE,e[8]*a[8]+a[8]+20,HEIGHT/2-20,40,40,0,360*64); //Создания надписей fclrs.pixel = 0; fclrs.red = 0xFFFF; fclrs.green = 0; fclrs.blue = 0; gdk_gc_set_rgb_fg_color(gc,&fclrs); gdk_draw_string(widget->window,font,gc,x[8]-25,y[8]-10,name[8]); gdk_draw_string(widget->window,font,gc,x[7]-30,y[7]-16,name[7]); gdk_draw_string(widget->window,font,gc,x[6]-20,y[6]-13,name[6]); gdk_draw_string(widget->window,font,gc,x[5]-30,y[5]-20,name[5]); gdk_draw_string(widget->window,font,gc,x[4]-30,y[4]-20,name[4]); gdk_draw_string(widget->window,font,gc,x[3]-20,y[3]-13,name[3]); gdk_draw_string(widget->window,font,gc,x[2]-20,y[2]-13,name[2]); gdk_draw_string(widget->window,font,gc,x[1]-30,y[1]-20,name[1]); gdk_draw_string(widget->window,font,gc,x[0]-30,y[0]-20,name[0]); //Создания надписи солнца gdk_draw_string(widget->window,font,gc,e[8]*a[8]+a[8]+25,HEIGHT/2+5,"Sun"); //увеличить счётчик изменений параметра у каждой планеты for(i=0;i<9;i++) { num_change_t[i]++; } //увеличение параметра согласно произведения реальной скорости планеты на опр. коофициент for(i=0;i<9;i++) { t[i]+=speed_change_t*v[i]; } return TRUE; }
Ключевые слова:
Солнечная система
|
|||||||