Среда программирования:
Code::Blocks
Статья по теме:
Построим аксонометрическую косоугольную фронтальную диметрическую проекцию пирамиды и аксонометрическую косоугольную горизонтальную изометрическую проекцию пирамиды.
(координата z вершины была увеличена для более показательной разницы между проекциями)
Код программы:
#include <gtk/gtk.h> // подключаем GTK+ #include <cairo.h> // подключаем библиотеку векторной графики Cairo #include <math.h> // подключаем библиотеку математических функций и констант #include <stdlib.h> #include <time.h> #define M 5 int k=2,size_w=300,size_h=300; /* Функция, вызываемая на перерисовку содержимого окна */ void draw_figure(cairo_t *cr,int figure2[M][2]) { int i; cairo_set_source_rgb(cr, 1.0, 0, 0.0); cairo_move_to(cr,figure2[0][0],figure2[0][1]); for(i=1;i<M-1;i++) cairo_line_to(cr,figure2[i][0],figure2[i][1]); cairo_line_to(cr,figure2[0][0],figure2[0][1]); for(i=0;i<M-1;i++) { cairo_move_to(cr,figure2[M-1][0],figure2[M-1][1]); cairo_line_to(cr,figure2[i][0],figure2[i][1]); } cairo_stroke(cr); } void draw_coord(cairo_t *cr,int x0,int y0, int x1, int y1, int x2,int y2, int x3, int y3) { cairo_move_to(cr,x0,y0); cairo_line_to(cr,x1,y1); cairo_move_to(cr,x0,y0); cairo_line_to(cr,x2,y2); cairo_move_to(cr,x0,y0); cairo_line_to(cr,x3,y3); cairo_set_source_rgb(cr, 0, 0, 0.0); cairo_stroke(cr); } void on_draw_event (GtkWidget *widget, cairo_t *cr, gpointer data) { int figure[M][3]={{100,150,1},{130,-30,1},{100,-110,1},{-100,-95,1},{200,-100,50}}; int i,j; int figure2[M][2]; int x,y,z; for(i=0;i<M;i++) { x=figure[i][0]; y=-1*figure[i][1]; z=figure[i][2]; figure2[i][0]=x+z*cos(135*M_PI/180)*0.5+size_w/2; figure2[i][1]=y+z*sin(135*M_PI/180)*0.5+size_h*1/2; } draw_coord(cr, size_w/2,size_h/2,size_w ,size_h/2,size_w/2, 0, size_w*(cos(135*M_PI/180)/2+1/2),size_h+size_w*sin(135*M_PI/180)/2); draw_figure(cr,figure2);//Аксонометрическая прямоугольная изометрическая проекция for(i=0;i<M;i++) { x=figure[i][0]; y=-1*figure[i][1]; z=figure[i][2]; figure2[i][0]=x+z*cos(150*M_PI/180)+size_w*2; figure2[i][1]=y+z*sin(150*M_PI/180)+size_h*1/2; } draw_coord(cr, size_w*2, size_h/2, size_w*5/2 , size_h/2, size_w*2, 0, size_w*(cos(150*M_PI/180)/2+2),size_h/2+size_w*sin(150*M_PI/180)/2); draw_figure(cr,figure2);//Аксонометрическая косоугольная горизонтальная изометрическая проекция } void button_click (GtkButton *button, gpointer data, cairo_t *cr) { gtk_main_quit(); } /* Основная функция с которой стартует выполнение программы */ int main( int argc, char *argv[]) { /* запустить GTK+ */ gtk_init(&argc, &argv); /* создать новый виджет - окно и установить свойства*/ GtkWidget *window; window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), size_w*3, size_h*2); gtk_window_set_title(GTK_WINDOW(window), "Proetia"); gtk_container_set_border_width (GTK_CONTAINER (window), 10); /* Событие, которое отрабатывает на закрытие окна */ g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); /* создать виджет - вертикального расположения элементов */ GtkWidget *vbox; vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 1); gtk_container_add(GTK_CONTAINER (window), vbox); /* создать виджет - область для рисования */ GtkWidget *drawing_area; drawing_area = gtk_drawing_area_new(); /* разместить область в верхней части окна*/ gtk_box_pack_start (GTK_BOX(vbox), drawing_area, TRUE, TRUE, 10); /* Событие отрисовки содержимого области */ g_signal_connect(G_OBJECT(drawing_area), "draw", G_CALLBACK(on_draw_event), NULL); /* создать виджет - кнопка */ GtkWidget *button; button = gtk_button_new_with_label("Quit"); gtk_container_set_border_width (GTK_CONTAINER (button), 10); /* разместить кнопку в нижней части окна*/ gtk_box_pack_end (GTK_BOX(vbox), button, FALSE, FALSE, 10); /* Событие, которое отрабатывает на нажатие кнопки */ g_signal_connect(GTK_BUTTON(button), "clicked", G_CALLBACK(button_click), NULL); /* отобразить окно и все его виджеты */ gtk_widget_show_all(window); /* передаём управление GTK+ */ gtk_main(); return 0; }