Data de publicació: Mar 15, 2018 8:58:4 AM
//gcc cairo_poligon_fractal.c -lm `pkg-config --cflags gtk+-3.0 --libs gtk+-3.0` -o cairo_poligon_fractal
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
//Screen dimension in pixels
#define WIDTH 1000
#define HEIGHT 1000
//Polygon type and radius dimension
#define N_POL 3
#define RADI ( WIDTH / 2 )
#define DIV 2
//N_PLACES 0, Next vertex selected not the same vertex, 1: Not the next vertex in order, and so on ...
#define N_PLACES 2
//Anula N_PLACES. ALL 1, all vertex possible selected
#define ALL 1
typedef struct punt{
int x;
int y;
} t_punt;
t_punt POLIGON[N_POL], punt;
int _genera_poligon(t_punt POLIGON[], int n, int r){
int i;
for (i = 0; i < n; i++) {
POLIGON[i].x = (int)(r - r * sinf(2 * M_PI * i / n));
POLIGON[i].y = (int)(r - r * cosf(2 * M_PI * i / n));
}
}
void _init_aleat(){srand(time(NULL));}
int _aleat(int n){return rand() % n;}
void _wait_for(int n){int i; for ( i = 0; i < n; i++ );}
int _aleat_diff(int n_pol, int vertex){
int v;
v = _aleat(n_pol);
while ( v == vertex ) v = _aleat(N_POL);
return v;
}
int _nplaces_away_from_vertex(int vertex, int n_places, int n_pol){return ( (vertex + n_places) % n_pol );}
gboolean draw_callback(GtkWidget *widget,cairo_t *cr,gpointer data){
guint width, height;
GdkRGBA color;
GtkStyleContext *context;
int i, vertex;
context = gtk_widget_get_style_context(widget);
width = gtk_widget_get_allocated_width(widget);
height = gtk_widget_get_allocated_height(widget);
gtk_render_background(context, cr, 0, 0, width, height);
//Constructing and painting the polygon
_genera_poligon(POLIGON, N_POL, RADI);
for ( i = 0; i < N_POL; i++ ){
cairo_move_to (cr, POLIGON[i].x, POLIGON[i].y);
cairo_line_to (cr, POLIGON[(i+1)%N_POL].x, POLIGON[(i+1)%N_POL].y);
}
//Set source color black, and the line width
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_set_line_width (cr, 1.0);
//Paint the polygon
cairo_stroke (cr);
vertex = _aleat(N_POL);
for ( i = 0; i < 100000; i++ ) {
_wait_for(1);
cairo_move_to (cr, punt.x, punt.y);
cairo_arc(cr, punt.x, punt.y, 0.05, 0, 2*G_PI);
switch ( ALL ){
case 1: vertex = _aleat( N_POL ); break;
case 0: vertex = _aleat_diff(N_POL, _nplaces_away_from_vertex(vertex, N_PLACES, N_POL));break;
default: break;
}
punt.x = punt.x + (POLIGON[vertex].x - punt.x) / DIV;
punt.y = punt.y + (POLIGON[vertex].y - punt.y) / DIV;
cairo_stroke (cr);
cairo_fill(cr);
}
gtk_style_context_get_color(context,gtk_style_context_get_state(context),&color);
gdk_cairo_set_source_rgba(cr,&color);
//gdk_cairo_set_source_rgba(cr,&color);
cairo_fill (cr);
return FALSE;
}
//-------------------------------------------------------------------
gint main(int argc,char *argv[])
{
GtkWidget *window,*drawing_area;
gtk_init(&argc,&argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
drawing_area=gtk_drawing_area_new();
gtk_container_add (GTK_CONTAINER (window),drawing_area);
gtk_widget_set_size_request(drawing_area, WIDTH, HEIGHT);
g_signal_connect(G_OBJECT(drawing_area),"draw", G_CALLBACK(draw_callback),NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}