Построить фрактал Коха, менять динамически параметры фрактала. Данная программа на основе построение кривой Коха, строит Каждую секунду увеличивается степень кривизны объекта. Алгоритм: где, Для построение снежинки Коха. квадрата Коха и т д. #include <stdio.h> #include <math.h> #include <gtk/gtk.h> #include <stdlib.h> #include <time.h> typedef struct TRANSP trans;//структура передачи struct TRANSP{ int o;//порядок искривления int switcer;//переключатель кривых GtkWidget *window_tr;//где рисуем }; //фун-ия дробления прямой void KOH(GtkWidget *w, int k, int o, int x1, int y1, int x2, int y2, int i){ cairo_t *cr; cr = gdk_cairo_create (w); cairo_set_line_width(cr, 5); cairo_set_source_rgb(cr, 0, 0, 0); // точка на 1/3 длины double x3 = x1 + (x2 - x1)/3; double y3 = y1 + (y2 - y1)/3; // точка на 2/3 длины double y4 = y1 + 2 * (y2 - y1)/3; double x4 = x1 + 2 * (x2 - x1)/3; //закрашиваем среднюю треть прямой cairo_line_to(cr, x3, y3); cairo_line_to(cr, x4, y4); cairo_stroke (cr); // длина линии double L = sqrt(pow((x1 - x2),2) + pow((y1 - y2),2)); // высота нового равностороннего треугольника double h = L /(2 * sqrt(3)); // углы между линией и осью ОХ double sina = (y2 - y1)/L; double cosa = (x2 - x1)/L; // вершина галочки double x5 = (x2 + x1)/2 + h * i * sina; double y5 = (y2 + y1)/2 - h * i * cosa ; // рисуем "галочку" cairo_set_source_rgb(cr, 0, 1, 0); cairo_set_line_width (cr, 2); cairo_line_to(cr, x3, y3); cairo_line_to(cr, x5, y5); cairo_line_to(cr, x5, y5); cairo_line_to(cr, x4, y4); cairo_stroke (cr); k++;// текущий порядок кривй Коха if (k<o){// рекурсивно вызываем эту фи-ию пока порядок кривизны не будет равен данному KOH(w, k, o, x1, y1, x3, y3, i); KOH(w, k, o, x3, y3, x5, y5, i); KOH(w, k, o, x5, y5, x4, y4, i); KOH(w, k, o, x4, y4, x2, y2, i); } cairo_destroy(cr); } gboolean on_draw (GtkWidget *widget, GdkEventExpose *event, gpointer data){ trans *h; h=(trans*)data; int o, switcer; o=h->o; switcer=h->switcer; cairo_t *cr; cr = gdk_cairo_create (widget->window); //рисуем фон cairo_rectangle(cr, 0, 0, widget->allocation.width, widget->allocation.height); cairo_set_source_rgb(cr,0,0,0); cairo_fill(cr); // рисуем саму кривую cairo_set_source_rgb(cr,0,1,0); switch(switcer){ //обычеая кривая Коха (в основе лежит обычная прямая) case 1:{ int x1=20, y1=widget->allocation.height/2, x2=widget->allocation.width-20, y2=widget->allocation.height/2; int k=0; cairo_line_to(cr, x1, y1); cairo_line_to(cr, x2, y2); cairo_stroke (cr); cairo_destroy(cr); if (o>0) KOH(widget->window, k, o, x1, y1, x2, y2, 1); } break; //Двойная кривая Коха (в основе лежит обычная прямая, //но функциядробления вызывается 2 раза для верхнего искривлени и внутренего) case 2:{ int x1=20, y1=widget->allocation.height/2, x2=widget->allocation.width-20, y2=widget->allocation.height/2; int k=0; cairo_set_source_rgb(cr,0,1,0); cairo_line_to(cr, x1, y1); cairo_line_to(cr, x2, y2); cairo_stroke (cr); cairo_destroy(cr); if (o>0){ KOH(widget->window, k, o, x1, y1, x2, y2, 1); KOH(widget->window, k, o, x1, y1, x2, y2, -1); } } break; //квадрат коха (искревление идёт во внутрь) case 3:{ int l=50, x1=l, y1=l, x2=widget->allocation.width-l, y2=l, x3=l, y3=widget->allocation.height-l, x4=widget->allocation.width-l, y4=widget->allocation.height-l, k=0; cairo_line_to(cr, x1, y1); cairo_line_to(cr, x2, y2); cairo_line_to(cr, x1, y1); cairo_line_to(cr, x3, y3); cairo_line_to(cr, x3, y3); cairo_line_to(cr, x4, y4); cairo_line_to(cr, x2, y2); cairo_line_to(cr, x4, y4); cairo_stroke (cr); cairo_destroy(cr); if (o>0){ KOH(widget->window, k, o, x1, y1, x2, y2, -1); KOH(widget->window, k, o, x1, y1, x3, y3, 1); KOH(widget->window, k, o, x3, y3, x4, y4, 1); KOH(widget->window, k, o, x2, y2, x4, y4, -1); } } break; //Снежинка Коха (в основании лежит квадрат) case 4:{ int l=150, x1=l, y1=l, x2=widget->allocation.width-l, y2=l, x3=l, y3=widget->allocation.height-l, x4=widget->allocation.width-l, y4=widget->allocation.height-l, k=0; cairo_line_to(cr, x1, y1); cairo_line_to(cr, x2, y2); cairo_line_to(cr, x1, y1); cairo_line_to(cr, x3, y3); cairo_line_to(cr, x3, y3); cairo_line_to(cr, x4, y4); cairo_line_to(cr, x2, y2); cairo_line_to(cr, x4, y4); cairo_stroke (cr); cairo_destroy(cr); if (o>0){ KOH(widget->window, k, o, x1, y1, x2, y2, 1); KOH(widget->window, k, o, x1, y1, x3, y3, -1); KOH(widget->window, k, o, x3, y3, x4, y4, -1); KOH(widget->window, k, o, x2, y2, x4, y4, 1); } } break; //Снежинка Коха (в основании лежит правильный треугольник) case 5:{ int l=50, x2, y2, x3=l, y3=widget->allocation.height-l-100, x4=widget->allocation.width-l, y4=widget->allocation.height-l-100, k=0; x2=(x4-x3)*cos(-M_PI/3)+x3; y2=(x4-x3)*sin(-M_PI/3)+y3; cairo_line_to(cr, x3, y3); cairo_line_to(cr, x4, y4); cairo_line_to(cr, x3, y3); cairo_line_to(cr, x2, y2); cairo_line_to(cr, x2, y2); cairo_line_to(cr, x4, y4); cairo_stroke (cr); cairo_destroy(cr); if (o>0){ KOH(widget->window, k, o, x3, y3, x4, y4, -1); KOH(widget->window, k, o, x3, y3, x2, y2, 1); KOH(widget->window, k, o, x2, y2, x4, y4, 1); } } break; //Триугольник коха ( основании лежит правильный триугольник) case 6:{ int l=50, x2, y2, x3=l, y3=widget->allocation.height-l*2, x4=widget->allocation.width-l, y4=widget->allocation.height-l*2, k=0; x2=(x4-x3)*cos(-M_PI/3)+x3; y2=(x4-x3)*sin(-M_PI/3)+y3; cairo_line_to(cr, x3, y3); cairo_line_to(cr, x4, y4); cairo_line_to(cr, x3, y3); cairo_line_to(cr, x2, y2); cairo_line_to(cr, x2, y2); cairo_line_to(cr, x4, y4); cairo_stroke (cr); cairo_destroy(cr); if (o>0){ KOH(widget->window, k, o, x3, y3, x4, y4, 1); KOH(widget->window, k, o, x3, y3, x2, y2, -1); KOH(widget->window, k, o, x2, y2, x4, y4, -1); } } break; } return TRUE; } // Функ-ия каждую секнду перерисовывает кривую увеличвая порядок искривления gint time_step (gpointer data){ trans *l; l=(trans*)data; //GtkWidget *widget; //widget=(GtkWidget*)data; if (l->o>=5) l->o=0 ;//если порядок искривления больше 5 то возвращаемся к исходной кривой else l->o++; gtk_widget_queue_draw(l->window_tr); return 1; } //обработка нажатия клавиш gboolean on_press (GtkWidget *window, GdkEventKey *key, gpointer data){ trans *l; l=(trans*)data; l->o=0;//обнуляем порядок искривления switch(key->keyval){ //при нажатии клавиши 1 рисуется кривая 1 case 49: l->switcer=1; break; //при нажатии клавиши 2 рисуется кривая 2 case 50: l->switcer=2; break; //при нажатии клавиши 3 рисуется кривая 3 case 51: l->switcer=3; break; //при нажатии клавиши 4 рисуется кривая 4 case 52: l->switcer=4; break; //при нажатии клавиши 5 рисуется кривая 5 case 53: l->switcer=5; break; //при нажатии клавиши 6 рисуется кривая 6 case 54: l->switcer=6; break; } return 0; } int main (int argc, char *argv[]){ gtk_init( &argc, &argv);//инициализация GTK GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);// Создаём окно gtk_widget_set_size_request (window, 600, 600);// Размерность окна trans fd; fd.o=0; fd.switcer=1; fd.window_tr=window; g_signal_connect (G_OBJECT (window), "expose_event", G_CALLBACK (on_draw),(gpointer)&fd);//при создании вы фу-ию рисования g_signal_connect (G_OBJECT (window), "key_press_event", G_CALLBACK (on_press), (gpointer)&fd);//обработчик события нажатия клвиш g_timeout_add(1000, (GSourceFunc) time_step, (gpointer)&fd);//перирисовка фрактала g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK(gtk_main_quit), NULL);//обработчик закрытия gtk_widget_show_all(window);// вывод окна gtk_main(); return 0; }
Ключевые слова:
кривая Коха, квадрат Коха, снежинка Коха, кривая Коха, фрактал
|
|||||||