В данной программе показан алгоритм размытия в движении. Язык С, реализовано на GTK и Cairo. Алгоритм: #include <stdlib.h> #include <gtk/gtk.h> typedef struct met met; typedef struct vars vars; struct met // структура описывающая шарики { float x0; float y0; float z0; float radi; float speed; float dts; float angle; float r,g,b; }; struct vars // структура для хранения данных программы { met *meteors; int mCount; GtkWidget *w; }; void init_met(met *m, float rad, float spx, float angl, float dist, float r, float g, float b) // инициализация шарика { m->x0 = 0; m->y0 = 0; m->speed = spx; m->radi = rad; m->angle = angl; m->dts = dist; m->r = r; m->g = g; m->b = b; } void init_vars(vars *v,GtkWidget *wd, int count) // инициализация всех переменных программы { v->w = wd; v->mCount = count; v->meteors = (met *) malloc(sizeof(met)*count); int i=0; for(;i<count; i++) { init_met(&v->meteors[i],19+rand()%20, (((float) 6+rand()%10)/10) * pow(-1,rand()%2), rand()%360, 70 + (35+rand()%10) * (i+1), (rand()%9) / 10.0, (rand()%9) / 10.0, (rand()%9) / 10.0); } } gint draw_met(vars *v,met *m) // прорисовка шарика { cairo_t *cr = gdk_cairo_create(v->w->window); cairo_pattern_t *pt; cairo_set_line_width(cr,0.1); pt = cairo_pattern_create_radial(m->x0,m->y0,0,m->x0,m->y0,m->radi); cairo_pattern_add_color_stop_rgba(pt,0.2,m->r,m->g,m->b,0.5); cairo_pattern_add_color_stop_rgba(pt,0.9,0,0,0.0,0.05); cairo_arc(cr,m->x0,m->y0,m->radi,0,360); cairo_set_source(cr, pt); cairo_fill(cr); cairo_pattern_destroy(pt); cairo_destroy(cr); return 1; } gint draw(GtkWidget *w, GdkEventExpose *event, gpointer *data) // прорисовка начального состоЯния окна { cairo_t *cr = gdk_cairo_create(w->window); cairo_set_source_rgb(cr, 0, 0, 0); cairo_rectangle (cr, 0, 0, 800, 800); cairo_fill(cr); cairo_destroy(cr); return 1; } gint tail(vars *v) // функция создает эффект "хвоста" за шариком { // эффект хвоста предельно прост cairo_t *cr = gdk_cairo_create(v->w->window); // инициализация cairo cairo_set_source_rgba(cr, 0, 0, 0,0.06); // задаем очень прозрачный цвет для заливки cairo_rectangle (cr, 0, 0, 800, 800); // накладываем на всю картинку прозрачный слой cairo_fill(cr); // закрашиваем // // далее рисуем центральный шар cairo_pattern_t *pt = cairo_pattern_create_radial(350,350,0,350,350,80); // создаем тип заливки - круговой градиент cairo_pattern_add_color_stop_rgba(pt,0.2,cos(v->meteors[0].angle),sin(v->meteors[0].angle),0.8,0.5); // указываем начальный цвет cairo_pattern_add_color_stop_rgba(pt,0.9,0,0,0.0,0.01); // указываем конечный цвет cairo_arc(cr,350,350,90,0,360); // рисуем окружность cairo_set_source(cr, pt); // передаем параметры заливки cairo_fill(cr); // заливаем окружность cairo_pattern_destroy(pt); // отчищаем память cairo_destroy(cr); // отчищаем память return 1; } gint timer(gpointer data) { vars *v = (vars *) data; int i; for(i=0;i<v->mCount;i++) // перемещаем шарики по траектории заданной произвольной функцией=) { v->meteors[i].z0 = v->meteors[i].dts/5 * (cos((v->meteors[i].angle+=v->meteors[i].speed) * 3.1415/180) * (1 - cos(v->meteors[i].angle * 3.1415/180))); v->meteors[i].x0 =350 + ((v->meteors[i].dts * sin(v->meteors[i].angle * 3.1415/180))); v->meteors[i].y0 =350 + ((-v->meteors[i].dts * cos(v->meteors[i].angle * 3.1415/180))); v->meteors[i].x0 = v->meteors[i].x0/(1 - v->meteors[i].z0/50.0); v->meteors[i].y0 = v->meteors[i].y0/(1 - v->meteors[i].z0/50.0); draw_met(v,&v->meteors[i]); // прорисовываем шарик if(v->meteors[i].angle >= 360 || v->meteors[i].angle <= -360) { v->meteors[i].angle = 0; } } tail(v); } int main (int argc, char *argv[]) { srand(time(0)); vars v; GtkWidget *win = NULL; g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL); gtk_init (&argc, &argv); g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL); win = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_container_set_border_width (GTK_CONTAINER (win), 8); gtk_window_set_title (GTK_WINDOW (win), "Picture"); gtk_widget_set_size_request(win,700,700); gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER); gtk_widget_realize (win); g_signal_connect (win, "destroy", gtk_main_quit, NULL); g_signal_connect (win, "expose_event", G_CALLBACK(draw), NULL); gtk_widget_show_all (win); init_vars(&v,win, 5); gtk_timeout_add(25,timer,(gpointer)&v); gtk_main (); return 0; }
Ключевые слова:
gtk gtk+ cairo размытие движения
|
|||||||