boxes, attractors and everything
This commit is contained in:
parent
09a43c7ac3
commit
c3deff6d64
88
initcairo.c
88
initcairo.c
@ -12,8 +12,28 @@ static Bool alwaysTruePredicate(Display *display, XEvent *event, XPointer arg)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int initCairo(int screen, int mask, int width, int height, const char *name, GraphicsInfo *info)
|
void updateDimensions(DrawingContext *ctx)
|
||||||
{
|
{
|
||||||
|
double det = ctx->matrix.xx * ctx->matrix.yy - ctx->matrix.xy * ctx->matrix.yx;
|
||||||
|
double cx = (double)ctx->width/2;
|
||||||
|
double cy = (double)ctx->height/2;
|
||||||
|
double r = 2*sqrt((cx*cx + cy*cy)/det); // this is not safe anymore if we have non-uniform scaling
|
||||||
|
|
||||||
|
// don't use cairo_device_to_user() since the matrix might not be our CTM yet
|
||||||
|
cx -= ctx->matrix.x0;
|
||||||
|
cy -= ctx->matrix.y0;
|
||||||
|
ctx->center_x = ( ctx->matrix.yy * cx - ctx->matrix.xy * cy) / det;
|
||||||
|
ctx->center_y = (- ctx->matrix.yx * cx + ctx->matrix.xx * cy) / det;
|
||||||
|
ctx->radius = r;
|
||||||
|
ctx->scalefactor = sqrt(det);
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphicsInfo *initCairo(int screen, int mask, int width, int height, const char *name)
|
||||||
|
{
|
||||||
|
GraphicsInfo *info = malloc(sizeof(GraphicsInfo));
|
||||||
|
DrawingContext *ctx = malloc(sizeof(DrawingContext));
|
||||||
|
info->context = ctx;
|
||||||
|
|
||||||
mask |= StructureNotifyMask | ExposureMask | KeyPressMask | ButtonPressMask | PointerMotionMask;
|
mask |= StructureNotifyMask | ExposureMask | KeyPressMask | ButtonPressMask | PointerMotionMask;
|
||||||
|
|
||||||
info->display = XOpenDisplay(NULL);
|
info->display = XOpenDisplay(NULL);
|
||||||
@ -34,17 +54,18 @@ int initCairo(int screen, int mask, int width, int height, const char *name, Gra
|
|||||||
|
|
||||||
XMapWindow(info->display, info->win);
|
XMapWindow(info->display, info->win);
|
||||||
|
|
||||||
info->sfc = cairo_xlib_surface_create(info->display, info->win, visual, width, height);
|
info->surface = cairo_xlib_surface_create(info->display, info->win, visual, width, height);
|
||||||
cairo_xlib_surface_set_size(info->sfc, width, height);
|
cairo_xlib_surface_set_size(info->surface, width, height);
|
||||||
info->ctx = cairo_create(info->sfc);
|
info->context->cairo = cairo_create(info->surface);
|
||||||
cairo_matrix_init_identity(&info->matrix);
|
cairo_matrix_init_identity(&info->context->matrix);
|
||||||
info->scalefactor = 1.0;
|
info->context->width = width;
|
||||||
|
info->context->height = height;
|
||||||
|
|
||||||
info->wm_delete_window = XInternAtom(info->display, "WM_DELETE_WINDOW", 0);
|
info->wm_delete_window = XInternAtom(info->display, "WM_DELETE_WINDOW", 0);
|
||||||
info->wm_protocols = XInternAtom(info->display, "WM_PROTOCOLS", 0);
|
info->wm_protocols = XInternAtom(info->display, "WM_PROTOCOLS", 0);
|
||||||
XSetWMProtocols(info->display, info->win, &info->wm_delete_window, 1);
|
XSetWMProtocols(info->display, info->win, &info->wm_delete_window, 1);
|
||||||
|
|
||||||
return 1;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroyCairo(GraphicsInfo *info)
|
void destroyCairo(GraphicsInfo *info)
|
||||||
@ -52,6 +73,8 @@ void destroyCairo(GraphicsInfo *info)
|
|||||||
XDestroyWindow(info->display, info->win);
|
XDestroyWindow(info->display, info->win);
|
||||||
XFreeColormap(info->display, info->cmap);
|
XFreeColormap(info->display, info->cmap);
|
||||||
XCloseDisplay(info->display);
|
XCloseDisplay(info->display);
|
||||||
|
free(info->context);
|
||||||
|
free(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void startTimer(GraphicsInfo *info)
|
void startTimer(GraphicsInfo *info)
|
||||||
@ -80,7 +103,7 @@ void waitUpdateTimer(GraphicsInfo *info)
|
|||||||
info->frames++;
|
info->frames++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int processStandardEvent(GraphicsInfo *info, XEvent *ev, void (*draw)(cairo_t *, void*), void *data)
|
int processStandardEvent(GraphicsInfo *info, XEvent *ev, void (*draw)(DrawingContext *))
|
||||||
{
|
{
|
||||||
int state;
|
int state;
|
||||||
static int last_x, last_y;
|
static int last_x, last_y;
|
||||||
@ -88,14 +111,15 @@ int processStandardEvent(GraphicsInfo *info, XEvent *ev, void (*draw)(cairo_t *,
|
|||||||
switch(ev->type) {
|
switch(ev->type) {
|
||||||
|
|
||||||
case Expose:
|
case Expose:
|
||||||
draw(info->ctx, data);
|
draw(info->context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ConfigureNotify:
|
case ConfigureNotify:
|
||||||
printf("ConfigureNotify Event, new dimensions: %d %d %d %d\n", ev->xconfigure.x, ev->xconfigure.y, ev->xconfigure.width, ev->xconfigure.height);
|
printf("ConfigureNotify Event, new dimensions: %d %d %d %d\n", ev->xconfigure.x, ev->xconfigure.y, ev->xconfigure.width, ev->xconfigure.height);
|
||||||
info->width = ev->xconfigure.width;
|
info->context->width = ev->xconfigure.width;
|
||||||
info->height = ev->xconfigure.height;
|
info->context->height = ev->xconfigure.height;
|
||||||
cairo_xlib_surface_set_size(info->sfc, info->width, info->height);
|
cairo_xlib_surface_set_size(info->surface, ev->xconfigure.width, ev->xconfigure.height);
|
||||||
|
draw(info->context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
@ -111,20 +135,19 @@ int processStandardEvent(GraphicsInfo *info, XEvent *ev, void (*draw)(cairo_t *,
|
|||||||
cairo_matrix_translate(&transform, ev->xbutton.x, ev->xbutton.y);
|
cairo_matrix_translate(&transform, ev->xbutton.x, ev->xbutton.y);
|
||||||
cairo_matrix_scale(&transform, 5.0/4.0, 5.0/4.0);
|
cairo_matrix_scale(&transform, 5.0/4.0, 5.0/4.0);
|
||||||
cairo_matrix_translate(&transform, -ev->xbutton.x, -ev->xbutton.y);
|
cairo_matrix_translate(&transform, -ev->xbutton.x, -ev->xbutton.y);
|
||||||
cairo_matrix_multiply(&info->matrix, &info->matrix, &transform);
|
cairo_matrix_multiply(&info->context->matrix, &info->context->matrix, &transform);
|
||||||
info->scalefactor *= 5.0/4.0;
|
draw(info->context);
|
||||||
} else if(ev->xbutton.button == 5) {
|
} else if(ev->xbutton.button == 5) {
|
||||||
cairo_matrix_t transform;
|
cairo_matrix_t transform;
|
||||||
cairo_matrix_init_identity(&transform);
|
cairo_matrix_init_identity(&transform);
|
||||||
cairo_matrix_translate(&transform, ev->xbutton.x, ev->xbutton.y);
|
cairo_matrix_translate(&transform, ev->xbutton.x, ev->xbutton.y);
|
||||||
cairo_matrix_scale(&transform, 4.0/5.0, 4.0/5.0);
|
cairo_matrix_scale(&transform, 4.0/5.0, 4.0/5.0);
|
||||||
cairo_matrix_translate(&transform, -ev->xbutton.x, -ev->xbutton.y);
|
cairo_matrix_translate(&transform, -ev->xbutton.x, -ev->xbutton.y);
|
||||||
cairo_matrix_multiply(&info->matrix, &info->matrix, &transform);
|
cairo_matrix_multiply(&info->context->matrix, &info->context->matrix, &transform);
|
||||||
info->scalefactor *= 4.0/5.0;
|
draw(info->context);
|
||||||
}
|
}
|
||||||
last_x = ev->xbutton.x;
|
last_x = ev->xbutton.x;
|
||||||
last_y = ev->xbutton.y;
|
last_y = ev->xbutton.y;
|
||||||
draw(info->ctx, data);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MotionNotify:
|
case MotionNotify:
|
||||||
@ -135,26 +158,23 @@ int processStandardEvent(GraphicsInfo *info, XEvent *ev, void (*draw)(cairo_t *,
|
|||||||
cairo_matrix_t transform;
|
cairo_matrix_t transform;
|
||||||
cairo_matrix_init_identity(&transform);
|
cairo_matrix_init_identity(&transform);
|
||||||
cairo_matrix_translate(&transform, dx, dy);
|
cairo_matrix_translate(&transform, dx, dy);
|
||||||
cairo_matrix_multiply(&info->matrix, &info->matrix, &transform);
|
cairo_matrix_multiply(&info->context->matrix, &info->context->matrix, &transform);
|
||||||
|
draw(info->context);
|
||||||
printf("Button1Motion Event, dx: %d, dy: %d\n", dx, dy);
|
|
||||||
|
|
||||||
draw(info->ctx, data);
|
|
||||||
} else if(ev->xmotion.state & Button1Mask && ev->xmotion.state & ShiftMask) {
|
} else if(ev->xmotion.state & Button1Mask && ev->xmotion.state & ShiftMask) {
|
||||||
|
double width = (double) cairo_xlib_surface_get_width(info->surface);
|
||||||
|
double height = (double) cairo_xlib_surface_get_height(info->surface);
|
||||||
|
|
||||||
double angle =
|
double angle =
|
||||||
atan2((double)ev->xmotion.y - (double)info->height/2, (double)ev->xmotion.x - (double)info->width/2)-
|
atan2((double)ev->xmotion.y - height/2, (double)ev->xmotion.x - width/2)-
|
||||||
atan2((double)last_y - (double)info->height/2, (double)last_x - (double)info->width/2);
|
atan2((double)last_y - height/2, (double)last_x - width/2);
|
||||||
|
|
||||||
cairo_matrix_t transform;
|
cairo_matrix_t transform;
|
||||||
cairo_matrix_init_identity(&transform);
|
cairo_matrix_init_identity(&transform);
|
||||||
cairo_matrix_translate(&transform, (double)info->width/2, (double)info->height/2);
|
cairo_matrix_translate(&transform, width/2, height/2);
|
||||||
cairo_matrix_rotate(&transform, angle);
|
cairo_matrix_rotate(&transform, angle);
|
||||||
cairo_matrix_translate(&transform, -(double)info->width/2, -(double)info->height/2);
|
cairo_matrix_translate(&transform, -width/2, -height/2);
|
||||||
cairo_matrix_multiply(&info->matrix, &info->matrix, &transform);
|
cairo_matrix_multiply(&info->context->matrix, &info->context->matrix, &transform);
|
||||||
|
draw(info->context);
|
||||||
printf("Button1Motion Event, angle: %f\n", angle);
|
|
||||||
|
|
||||||
draw(info->ctx, data);
|
|
||||||
}
|
}
|
||||||
last_x = ev->xmotion.x;
|
last_x = ev->xmotion.x;
|
||||||
last_y = ev->xmotion.y;
|
last_y = ev->xmotion.y;
|
||||||
@ -172,7 +192,7 @@ int processStandardEvent(GraphicsInfo *info, XEvent *ev, void (*draw)(cairo_t *,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int checkEvents(GraphicsInfo *info, int (*process)(GraphicsInfo*, XEvent*, void*), void (*draw)(cairo_t *, void*), void *data) // get any events from the queue and the server, process them if neccessary, quit if wanted
|
int checkEvents(GraphicsInfo *info, int (*process)(GraphicsInfo*, XEvent*), void (*draw)(DrawingContext*)) // get any events from the queue and the server, process them if neccessary, quit if wanted
|
||||||
{
|
{
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
|
|
||||||
@ -193,10 +213,10 @@ int checkEvents(GraphicsInfo *info, int (*process)(GraphicsInfo*, XEvent*, void*
|
|||||||
}
|
}
|
||||||
} */
|
} */
|
||||||
|
|
||||||
if(processStandardEvent(info, &ev, draw, data))
|
if(processStandardEvent(info, &ev, draw))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if(process(info, &ev, data))
|
if(process(info, &ev))
|
||||||
return 1; // quit event queue and application
|
return 1; // quit event queue and application
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
26
initcairo.h
26
initcairo.h
@ -13,27 +13,37 @@
|
|||||||
#include <cairo-xlib.h>
|
#include <cairo-xlib.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
cairo_t *cairo;
|
||||||
|
cairo_matrix_t matrix;
|
||||||
|
unsigned int width;
|
||||||
|
unsigned int height;
|
||||||
|
|
||||||
|
// these things will be written by updateDimensions()
|
||||||
|
double scalefactor;
|
||||||
|
double center_x;
|
||||||
|
double center_y;
|
||||||
|
double radius;
|
||||||
|
} DrawingContext;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
DrawingContext *context;
|
||||||
Display *display;
|
Display *display;
|
||||||
Window win;
|
Window win;
|
||||||
Colormap cmap;
|
Colormap cmap;
|
||||||
Atom wm_protocols;
|
Atom wm_protocols;
|
||||||
Atom wm_delete_window;
|
Atom wm_delete_window;
|
||||||
cairo_surface_t *sfc;
|
cairo_surface_t *surface;
|
||||||
cairo_t *ctx;
|
|
||||||
struct timeval start_time;
|
struct timeval start_time;
|
||||||
unsigned long frames;
|
unsigned long frames;
|
||||||
double elapsed, frametime;
|
double elapsed, frametime;
|
||||||
unsigned int width;
|
|
||||||
unsigned int height;
|
|
||||||
cairo_matrix_t matrix;
|
|
||||||
double scalefactor;
|
|
||||||
} GraphicsInfo;
|
} GraphicsInfo;
|
||||||
|
|
||||||
int initCairo(int screen, int mask, int width, int height, const char *name, GraphicsInfo *info);
|
GraphicsInfo *initCairo(int screen, int mask, int width, int height, const char *name);
|
||||||
void destroyCairo(GraphicsInfo *info);
|
void destroyCairo(GraphicsInfo *info);
|
||||||
|
|
||||||
void startTimer(GraphicsInfo *info);
|
void startTimer(GraphicsInfo *info);
|
||||||
void waitUpdateTimer(GraphicsInfo *info);
|
void waitUpdateTimer(GraphicsInfo *info);
|
||||||
int checkEvents(GraphicsInfo *info, int (*process)(GraphicsInfo*, XEvent*, void*), void (*draw)(cairo_t *, void*), void *data);
|
int checkEvents(GraphicsInfo *info, int (*process)(GraphicsInfo*, XEvent*), void (*draw)(DrawingContext *));
|
||||||
|
void updateDimensions(DrawingContext *ctx);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
530
limit_set.c
530
limit_set.c
@ -1,6 +1,8 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <cairo/cairo-pdf.h>
|
||||||
#include <X11/XKBlib.h>
|
#include <X11/XKBlib.h>
|
||||||
|
|
||||||
#include "initcairo.h"
|
#include "initcairo.h"
|
||||||
@ -14,19 +16,27 @@ typedef struct {
|
|||||||
double y;
|
double y;
|
||||||
} point_t;
|
} point_t;
|
||||||
|
|
||||||
int processEvent(GraphicsInfo *info, XEvent *ev, void *data);
|
|
||||||
void setup();
|
|
||||||
void destroy();
|
|
||||||
void cartanMatrix(gsl_matrix *cartan, double a1, double a2, double a3, double s);
|
void cartanMatrix(gsl_matrix *cartan, double a1, double a2, double a3, double s);
|
||||||
void initializeTriangleGenerators(gsl_matrix **gen, gsl_matrix *cartan);
|
void initializeTriangleGenerators(gsl_matrix **gen, gsl_matrix *cartan);
|
||||||
|
point_t intersect(point_t a, point_t b, point_t c, point_t d);
|
||||||
|
void drawPoint(DrawingContext *ctx, point_t p);
|
||||||
|
void drawSegment(DrawingContext *ctx, point_t a, point_t b);
|
||||||
|
void drawLine(DrawingContext *ctx, point_t a, point_t b);
|
||||||
|
void drawImplicitLine(DrawingContext *ctx, double a, double b, double c);
|
||||||
|
void drawPolygon(DrawingContext *ctx, int sides, point_t a, point_t b, point_t c, point_t d);
|
||||||
|
void drawAttractorConnection(DrawingContext *ctx, const char *word1, const char *word2);
|
||||||
|
void drawBox(DrawingContext *ctx, const char *word1, const char *word2);
|
||||||
|
void drawBoxStd(DrawingContext *ctx, const char *word, char base);
|
||||||
int compareAngle(const void *x, const void *y);
|
int compareAngle(const void *x, const void *y);
|
||||||
int computeLimitCurve();
|
int computeLimitCurve();
|
||||||
void draw(cairo_t *ctx, void *data);
|
void drawBoxes(DrawingContext *ctx);
|
||||||
point_t intersect(point_t a, point_t b, point_t c, point_t d);
|
void drawReflectors(DrawingContext *ctx);
|
||||||
void drawBoxStd(cairo_t *ctx, const char *word, char base);
|
void drawAttractors(DrawingContext *ctx);
|
||||||
void drawBox(cairo_t *ctx, const char *word1, const char *word2);
|
void draw(DrawingContext *ctx);
|
||||||
|
void setup();
|
||||||
GraphicsInfo G;
|
void destroy();
|
||||||
|
void print(DrawingContext *screen);
|
||||||
|
int processEvent(GraphicsInfo *info, XEvent *ev);
|
||||||
|
|
||||||
double parameter;
|
double parameter;
|
||||||
int n_group_elements;
|
int n_group_elements;
|
||||||
@ -40,97 +50,9 @@ gsl_matrix *cartan, *cob, *coxeter, *coxeter_fixedpoints, *fixedpoints;
|
|||||||
|
|
||||||
int show_boxes = 0;
|
int show_boxes = 0;
|
||||||
int show_attractors = 0;
|
int show_attractors = 0;
|
||||||
|
int show_reflectors = 0;
|
||||||
int show_limit = 1;
|
int show_limit = 1;
|
||||||
|
|
||||||
int processEvent(GraphicsInfo *info, XEvent *ev, void *data)
|
|
||||||
{
|
|
||||||
int state;
|
|
||||||
unsigned long key;
|
|
||||||
|
|
||||||
switch(ev->type) {
|
|
||||||
|
|
||||||
case KeyPress:
|
|
||||||
state = ev->xkey.state & (ShiftMask | LockMask | ControlMask);
|
|
||||||
key = XkbKeycodeToKeysym(ev->xkey.display, ev->xkey.keycode, 0, !!(state & ShiftMask));
|
|
||||||
printf("Key pressed: %ld\n", key);
|
|
||||||
|
|
||||||
switch(key) {
|
|
||||||
case '<':
|
|
||||||
parameter /= exp(0.002);
|
|
||||||
limit_curve_valid = computeLimitCurve();
|
|
||||||
break;
|
|
||||||
case '>':
|
|
||||||
parameter *= exp(0.002);
|
|
||||||
limit_curve_valid = computeLimitCurve();
|
|
||||||
break;
|
|
||||||
case ' ':
|
|
||||||
parameter = 2.890053638;
|
|
||||||
limit_curve_valid = computeLimitCurve();
|
|
||||||
break;
|
|
||||||
case XK_Return:
|
|
||||||
parameter = 2.76375163;
|
|
||||||
limit_curve_valid = computeLimitCurve();
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
printf("G.matrix.xx = %f;\n", G.matrix.xx);
|
|
||||||
printf("G.matrix.xy = %f;\n", G.matrix.xy);
|
|
||||||
printf("G.matrix.x0 = %f;\n", G.matrix.x0);
|
|
||||||
printf("G.matrix.yx = %f;\n", G.matrix.yx);
|
|
||||||
printf("G.matrix.yy = %f;\n", G.matrix.yy);
|
|
||||||
printf("G.matrix.y0 = %f;\n", G.matrix.y0);
|
|
||||||
printf("G.scalefactor = %f;\n", G.scalefactor);
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
show_boxes = !show_boxes;
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
show_attractors = !show_attractors;
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
show_limit = !show_limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
draw(G.ctx, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
n_group_elements = 10000;
|
|
||||||
limit_curve = malloc(3*n_group_elements*sizeof(double));
|
|
||||||
group = malloc(n_group_elements*sizeof(groupelement_t));
|
|
||||||
ws = workspace_alloc(3);
|
|
||||||
|
|
||||||
LOOP(i) gen[i] = gsl_matrix_alloc(3, 3);
|
|
||||||
matrices = malloc(n_group_elements*sizeof(gsl_matrix*));
|
|
||||||
for(int i = 0; i < n_group_elements; i++)
|
|
||||||
matrices[i] = gsl_matrix_alloc(3, 3);
|
|
||||||
cartan = gsl_matrix_alloc(3, 3);
|
|
||||||
cob = gsl_matrix_alloc(3, 3);
|
|
||||||
coxeter = gsl_matrix_alloc(3, 3);
|
|
||||||
coxeter_fixedpoints = gsl_matrix_alloc(3, 3);
|
|
||||||
fixedpoints = gsl_matrix_alloc(3, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroy()
|
|
||||||
{
|
|
||||||
free(limit_curve);
|
|
||||||
free(group);
|
|
||||||
workspace_free(ws);
|
|
||||||
|
|
||||||
LOOP(i) gsl_matrix_free(gen[i]);
|
|
||||||
for(int i = 0; i < n_group_elements; i++)
|
|
||||||
gsl_matrix_free(matrices[i]);
|
|
||||||
free(matrices);
|
|
||||||
gsl_matrix_free(cartan);
|
|
||||||
gsl_matrix_free(cob);
|
|
||||||
gsl_matrix_free(coxeter);
|
|
||||||
gsl_matrix_free(coxeter_fixedpoints);
|
|
||||||
gsl_matrix_free(fixedpoints);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cartanMatrix(gsl_matrix *cartan, double a1, double a2, double a3, double s)
|
void cartanMatrix(gsl_matrix *cartan, double a1, double a2, double a3, double s)
|
||||||
{
|
{
|
||||||
gsl_matrix_set(cartan, 0, 0, -2);
|
gsl_matrix_set(cartan, 0, 0, -2);
|
||||||
@ -152,11 +74,6 @@ void initializeTriangleGenerators(gsl_matrix **gen, gsl_matrix *cartan)
|
|||||||
LOOP(i) LOOP(j) *gsl_matrix_ptr(gen[i], i, j) += gsl_matrix_get(cartan, i, j);
|
LOOP(i) LOOP(j) *gsl_matrix_ptr(gen[i], i, j) += gsl_matrix_get(cartan, i, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
int compareAngle(const void *x, const void *y)
|
|
||||||
{
|
|
||||||
return ((double*)x)[2] > ((double*)y)[2] ? 1 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// intersect the lines a-b and c-d
|
// intersect the lines a-b and c-d
|
||||||
point_t intersect(point_t a, point_t b, point_t c, point_t d)
|
point_t intersect(point_t a, point_t b, point_t c, point_t d)
|
||||||
{
|
{
|
||||||
@ -167,31 +84,72 @@ point_t intersect(point_t a, point_t b, point_t c, point_t d)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawPoint(cairo_t *ctx, point_t p)
|
void drawPoint(DrawingContext *ctx, point_t p)
|
||||||
|
{
|
||||||
|
cairo_t *C = ctx->cairo;
|
||||||
|
|
||||||
|
cairo_save(C);
|
||||||
|
cairo_move_to(C, p.x, p.y);
|
||||||
|
cairo_close_path(C);
|
||||||
|
cairo_set_line_cap(C, CAIRO_LINE_CAP_ROUND);
|
||||||
|
cairo_set_line_width(C, 10.0/ctx->scalefactor);
|
||||||
|
cairo_stroke(C);
|
||||||
|
cairo_restore(C);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawSegment(DrawingContext *ctx, point_t a, point_t b)
|
||||||
|
{
|
||||||
|
cairo_t *C = ctx->cairo;
|
||||||
|
cairo_move_to(C, a.x, a.y);
|
||||||
|
cairo_line_to(C, b.x, b.y);
|
||||||
|
cairo_stroke(C);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawLine(DrawingContext *ctx, point_t a, point_t b)
|
||||||
{
|
{
|
||||||
// not implemented
|
// not implemented
|
||||||
cairo_save(ctx);
|
point_t c, xplus, xminus;
|
||||||
cairo_move_to(ctx, p.x, p.y);
|
double normb;
|
||||||
cairo_close_path(ctx);
|
double scalbc;
|
||||||
cairo_set_line_cap(ctx, CAIRO_LINE_CAP_ROUND);
|
|
||||||
cairo_set_line_width(ctx, 10.0/G.scalefactor);
|
c.x = ctx->center_x;
|
||||||
cairo_stroke(ctx);
|
c.y = ctx->center_y;
|
||||||
cairo_restore(ctx);
|
b.x -= a.x;
|
||||||
|
b.y -= a.y;
|
||||||
|
c.x -= a.x;
|
||||||
|
c.y -= a.y;
|
||||||
|
normb = sqrt(b.x*b.x + b.y*b.y);
|
||||||
|
b.x /= normb;
|
||||||
|
b.y /= normb;
|
||||||
|
scalbc = b.x*c.x + b.y*c.y;
|
||||||
|
xplus.x = a.x + (scalbc + ctx->radius)*b.x;
|
||||||
|
xplus.y = a.y + (scalbc + ctx->radius)*b.y;
|
||||||
|
xminus.x = a.x + (scalbc - ctx->radius)*b.x;
|
||||||
|
xminus.y = a.y + (scalbc - ctx->radius)*b.y;
|
||||||
|
|
||||||
|
drawSegment(ctx, xminus, xplus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawLine(cairo_t *ctx, point_t a, point_t b)
|
void drawImplicitLine(DrawingContext *ctx, double a, double b, double c)
|
||||||
{
|
{
|
||||||
// not implemented
|
// not implemented
|
||||||
|
double norm, lambda;
|
||||||
|
point_t m, s, xminus, xplus;
|
||||||
|
m.x = ctx->center_x;
|
||||||
|
m.y = ctx->center_y;
|
||||||
|
lambda = (a*m.x + b*m.y + c)/(a*a + b*b);
|
||||||
|
s.x = m.x - lambda*a;
|
||||||
|
s.y = m.y - lambda*b;
|
||||||
|
norm = sqrt(a*a + b*b);
|
||||||
|
xminus.x = s.x - ctx->radius * b / norm;
|
||||||
|
xminus.y = s.y + ctx->radius * a / norm;
|
||||||
|
xplus.x = s.x + ctx->radius * b / norm;
|
||||||
|
xplus.y = s.y - ctx->radius * a / norm;
|
||||||
|
|
||||||
|
drawSegment(ctx, xminus, xplus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawSegment(cairo_t *ctx, point_t a, point_t b)
|
void drawPolygon(DrawingContext *ctx, int sides, point_t a, point_t b, point_t c, point_t d) // only quadrilaterals so far
|
||||||
{
|
|
||||||
cairo_move_to(ctx, a.x, a.y);
|
|
||||||
cairo_line_to(ctx, b.x, b.y);
|
|
||||||
cairo_stroke(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawPolygon(cairo_t *ctx, int sides, point_t a, point_t b, point_t c, point_t d) // only quadrilaterals so far
|
|
||||||
{
|
{
|
||||||
drawSegment(ctx, a, b);
|
drawSegment(ctx, a, b);
|
||||||
drawSegment(ctx, b, c);
|
drawSegment(ctx, b, c);
|
||||||
@ -217,7 +175,7 @@ void fixedPoints(const char *word, point_t *out)
|
|||||||
LOOP(i) out[i].y = gsl_matrix_get(ev, 1, i) / gsl_matrix_get(ev, 2, i);
|
LOOP(i) out[i].y = gsl_matrix_get(ev, 1, i) / gsl_matrix_get(ev, 2, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawAttractorConnection(cairo_t *ctx, const char *word1, const char *word2)
|
void drawAttractorConnection(DrawingContext *ctx, const char *word1, const char *word2)
|
||||||
{
|
{
|
||||||
point_t p1[3], p2[3];
|
point_t p1[3], p2[3];
|
||||||
|
|
||||||
@ -227,7 +185,7 @@ void drawAttractorConnection(cairo_t *ctx, const char *word1, const char *word2)
|
|||||||
drawSegment(ctx, p1[0], p2[0]);
|
drawSegment(ctx, p1[0], p2[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawBox(cairo_t *ctx, const char *word1, const char *word2)
|
void drawBox(DrawingContext *ctx, const char *word1, const char *word2)
|
||||||
{
|
{
|
||||||
point_t p[2][3],i[2];
|
point_t p[2][3],i[2];
|
||||||
|
|
||||||
@ -241,7 +199,7 @@ void drawBox(cairo_t *ctx, const char *word1, const char *word2)
|
|||||||
drawPolygon(ctx, 4, p[0][0], i[0], p[1][0], i[1]);
|
drawPolygon(ctx, 4, p[0][0], i[0], p[1][0], i[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawBoxStd(cairo_t *ctx, const char *word, char base)
|
void drawBoxStd(DrawingContext *ctx, const char *word, char base)
|
||||||
{
|
{
|
||||||
char word1[100];
|
char word1[100];
|
||||||
char word2[100];
|
char word2[100];
|
||||||
@ -265,6 +223,11 @@ void drawBoxStd(cairo_t *ctx, const char *word, char base)
|
|||||||
drawBox(ctx, word1, word2);
|
drawBox(ctx, word1, word2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int compareAngle(const void *x, const void *y)
|
||||||
|
{
|
||||||
|
return ((double*)x)[2] > ((double*)y)[2] ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
int computeLimitCurve()
|
int computeLimitCurve()
|
||||||
{
|
{
|
||||||
int p = 5, q = 5, r = 5;
|
int p = 5, q = 5, r = 5;
|
||||||
@ -314,85 +277,65 @@ int computeLimitCurve()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawBoxes(cairo_t *ctx)
|
void drawBoxes(DrawingContext *ctx)
|
||||||
{
|
{
|
||||||
cairo_set_source_rgb(ctx, 1, 0, 0);
|
cairo_t *C = ctx->cairo;
|
||||||
|
|
||||||
|
/*
|
||||||
|
cairo_set_source_rgb(C, 1, 0, 0);
|
||||||
drawBoxStd(ctx, "c", 'C');
|
drawBoxStd(ctx, "c", 'C');
|
||||||
drawBoxStd(ctx, "", 'B');
|
drawBoxStd(ctx, "", 'B');
|
||||||
drawBoxStd(ctx, "a", 'A');
|
drawBoxStd(ctx, "a", 'A');
|
||||||
drawBoxStd(ctx, "", 'C');
|
drawBoxStd(ctx, "", 'C');
|
||||||
// drawBoxStd(ctx, "", 'A');
|
|
||||||
drawBoxStd(ctx, "b", 'B');
|
drawBoxStd(ctx, "b", 'B');
|
||||||
|
*/
|
||||||
|
|
||||||
cairo_set_source_rgb(ctx, 0, 0, 1);
|
cairo_set_source_rgb(C, 0, 0, 0);
|
||||||
drawBoxStd(ctx, "ca", 'A');
|
drawBoxStd(ctx, "ca", 'A');
|
||||||
drawBoxStd(ctx, "cac", 'C');
|
drawBoxStd(ctx, "cac", 'C');
|
||||||
drawBoxStd(ctx, "caca", 'A');
|
drawBoxStd(ctx, "caca", 'A');
|
||||||
// drawBoxStd(ctx, "cacac", 'C');
|
|
||||||
// drawBoxStd(ctx, "acac", 'A');
|
|
||||||
// drawBoxStd(ctx, "aca", 'C');
|
|
||||||
|
|
||||||
cairo_set_source_rgb(ctx, 0, 1, 0);
|
|
||||||
drawBoxStd(ctx, "ac", 'C');
|
|
||||||
// drawBoxStd(ctx, "aca", 'A');
|
|
||||||
drawBoxStd(ctx, "acac", 'C');
|
drawBoxStd(ctx, "acac", 'C');
|
||||||
// drawBoxStd(ctx, "acaca", 'A');
|
drawBoxStd(ctx, "aca", 'A');
|
||||||
// drawBoxStd(ctx, "caca", 'C');
|
drawBoxStd(ctx, "ac", 'C');
|
||||||
// drawBoxStd(ctx, "cac", 'A');
|
|
||||||
|
|
||||||
cairo_set_source_rgb(ctx, 1, 0, 1);
|
cairo_set_source_rgb(C, 1, 0, 1);
|
||||||
|
|
||||||
|
/*
|
||||||
drawBoxStd(ctx, "aca cb", 'B');
|
drawBoxStd(ctx, "aca cb", 'B');
|
||||||
drawBoxStd(ctx, "aca cbc", 'C');
|
drawBoxStd(ctx, "aca cbc", 'C');
|
||||||
drawBoxStd(ctx, "aca cbcb", 'B');
|
drawBoxStd(ctx, "aca cbcb", 'B');
|
||||||
drawBoxStd(ctx, "aca bcbc", 'C');
|
drawBoxStd(ctx, "aca bcbc", 'C');
|
||||||
drawBoxStd(ctx, "aca bcb", 'B');
|
drawBoxStd(ctx, "aca bcb", 'B');
|
||||||
drawBoxStd(ctx, "aca bc", 'C');
|
drawBoxStd(ctx, "aca bc", 'C');
|
||||||
|
|
||||||
/*
|
|
||||||
cairo_set_source_rgb(ctx, 1, 0, 1);
|
|
||||||
drawAttractorConnection("acb", "acaba");
|
|
||||||
drawAttractorConnection("acaba", "acacbca");
|
|
||||||
drawAttractorConnection("ac acb ca", "ac acaba ca");
|
|
||||||
drawAttractorConnection("ac acaba ca", "ac acacbca ca");
|
|
||||||
drawAttractorConnection("acac acb caca", "acac acaba caca");
|
|
||||||
drawAttractorConnection("acac acaba caca", "acac acacbca caca");
|
|
||||||
drawAttractorConnection("caca acb acac", "caca acaba acac");
|
|
||||||
// drawAttractorConnection("caca acaba acac", "caca acacbca acac");
|
|
||||||
drawAttractorConnection("ca acb ac", "ca acaba ac");
|
|
||||||
drawAttractorConnection("ca acaba ac", "ca acacbca ac");
|
|
||||||
|
|
||||||
cairo_set_source_rgb(ctx, 0, 1, 0);
|
|
||||||
drawAttractorConnection("cab", "cacbc");
|
|
||||||
drawAttractorConnection("cacbc", "cacabac");
|
|
||||||
drawAttractorConnection("ca cab ac", "ca cacbc ac");
|
|
||||||
drawAttractorConnection("ca cacbc ac", "ca cacabac ac");
|
|
||||||
drawAttractorConnection("caca cab acac", "caca cacbc acac");
|
|
||||||
drawAttractorConnection("caca cacbc acac", "caca cacabac acac");
|
|
||||||
drawAttractorConnection("acac cab caca", "acac cacbc caca");
|
|
||||||
drawAttractorConnection("acac cacbc caca", "acac cacabac caca");
|
|
||||||
// drawAttractorConnection("ac cab ca", "ac cacbc ca");
|
|
||||||
drawAttractorConnection("ac cacbc ca", "ac cacabac ca");
|
|
||||||
*/
|
|
||||||
// finer box test
|
|
||||||
/*
|
|
||||||
cairo_set_source_rgb(ctx, 0, 1, 0);
|
|
||||||
drawBox("acb", "acabacaca");
|
|
||||||
drawBox("acabacaca", "acaba");
|
|
||||||
// drawBox("acb", "acaba");
|
|
||||||
drawBox("acaba", "acacbacac");
|
|
||||||
drawBox("acacbacac", "acacbca");
|
|
||||||
drawBox("acacbca", "cacacbcac");
|
|
||||||
drawBox("cacacbcac", "acacabaca");
|
|
||||||
drawBox("acacabaca", "cacabac");
|
|
||||||
drawBox("cacabac", "cacabcaca");
|
|
||||||
drawBox("cacabcaca", "cacbc");
|
|
||||||
// drawBox("cacbc", "cab");
|
|
||||||
drawBox("cacbc", "cacbcacac");
|
|
||||||
drawBox("cacbcacac", "cab"); // strange
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
drawBoxStd(ctx, "ca bc", 'C');
|
||||||
|
drawBoxStd(ctx, "ca bcb", 'B');
|
||||||
|
drawBoxStd(ctx, "ca bcbc", 'C');
|
||||||
|
drawBoxStd(ctx, "ca cbcb", 'B');
|
||||||
|
drawBoxStd(ctx, "ca cbc", 'C');
|
||||||
|
drawBoxStd(ctx, "ca cb", 'B');
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawAttractors(cairo_t *ctx)
|
void drawReflectors(DrawingContext *ctx)
|
||||||
|
{
|
||||||
|
gsl_matrix *tmp = ws->stack[10];
|
||||||
|
gsl_matrix *tmp2 = ws->stack[11];
|
||||||
|
point_t p[3];
|
||||||
|
|
||||||
|
// points
|
||||||
|
cairo_set_source_rgb(ctx->cairo, 0, 0, 0);
|
||||||
|
LOOP(i) p[i].x = gsl_matrix_get(cob, 0, i) / gsl_matrix_get(cob, 2, i);
|
||||||
|
LOOP(i) p[i].y = gsl_matrix_get(cob, 1, i) / gsl_matrix_get(cob, 2, i);
|
||||||
|
LOOP(i) drawPoint(ctx, p[i]);
|
||||||
|
|
||||||
|
// lines
|
||||||
|
invert(cob, tmp2, ws);
|
||||||
|
multiply(cartan, tmp2, tmp);
|
||||||
|
LOOP(i) drawImplicitLine(ctx, gsl_matrix_get(tmp, i, 0), gsl_matrix_get(tmp, i, 1), gsl_matrix_get(tmp, i, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawAttractors(DrawingContext *ctx)
|
||||||
{
|
{
|
||||||
point_t p[3][3];
|
point_t p[3][3];
|
||||||
|
|
||||||
@ -400,30 +343,39 @@ void drawAttractors(cairo_t *ctx)
|
|||||||
fixedPoints("bca", p[1]);
|
fixedPoints("bca", p[1]);
|
||||||
fixedPoints("cab", p[2]);
|
fixedPoints("cab", p[2]);
|
||||||
|
|
||||||
cairo_set_source_rgb(ctx, 0, 0, 0);
|
double color[3][3] = {{1,0,0},{0,0.7,0},{0,0,1}};
|
||||||
|
|
||||||
LOOP(i) LOOP(j) drawPoint(ctx, p[i][j]);
|
LOOP(i) LOOP(j) {
|
||||||
|
cairo_set_source_rgb(ctx->cairo, color[i][0], color[i][1], color[i][2]);
|
||||||
LOOP(i) LOOP(j) drawLine(ctx, p[i][j], p[i][(j+1)%3]);
|
drawPoint(ctx, p[i][j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(cairo_t *ctx, void *data)
|
LOOP(i) LOOP(j) {
|
||||||
|
cairo_set_source_rgb(ctx->cairo, color[i][0], color[i][1], color[i][2]);
|
||||||
|
drawLine(ctx, p[i][j], p[i][(j+1)%3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw(DrawingContext *ctx)
|
||||||
{
|
{
|
||||||
struct timeval current_time;
|
struct timeval current_time;
|
||||||
gettimeofday(¤t_time, 0);
|
gettimeofday(¤t_time, 0);
|
||||||
double start_time = current_time.tv_sec + current_time.tv_usec*1e-6;
|
double start_time = current_time.tv_sec + current_time.tv_usec*1e-6;
|
||||||
|
|
||||||
cairo_push_group(ctx);
|
cairo_t *C = ctx->cairo;
|
||||||
cairo_set_source_rgb(ctx, 1, 1, 1);
|
updateDimensions(ctx);
|
||||||
cairo_paint(ctx);
|
|
||||||
|
|
||||||
cairo_set_matrix(ctx, &G.matrix);
|
cairo_push_group(C);
|
||||||
|
cairo_set_source_rgb(C, 1, 1, 1);
|
||||||
|
cairo_paint(C);
|
||||||
|
|
||||||
|
cairo_set_matrix(C, &ctx->matrix);
|
||||||
|
|
||||||
// defaults; use save/restore whenever these are changed
|
// defaults; use save/restore whenever these are changed
|
||||||
cairo_set_line_width(ctx, 1.0/G.scalefactor);
|
cairo_set_line_width(C, 1.0/ctx->scalefactor);
|
||||||
cairo_set_font_size(ctx, 16);
|
cairo_set_font_size(C, 16);
|
||||||
cairo_set_line_join(ctx, CAIRO_LINE_JOIN_BEVEL);
|
cairo_set_line_join(C, CAIRO_LINE_JOIN_BEVEL);
|
||||||
cairo_set_line_cap(ctx, CAIRO_LINE_CAP_ROUND);
|
cairo_set_line_cap(C, CAIRO_LINE_CAP_ROUND);
|
||||||
|
|
||||||
if(limit_curve_valid) {
|
if(limit_curve_valid) {
|
||||||
|
|
||||||
@ -433,13 +385,13 @@ void draw(cairo_t *ctx, void *data)
|
|||||||
double x = limit_curve[3*i];
|
double x = limit_curve[3*i];
|
||||||
double y = limit_curve[3*i+1];
|
double y = limit_curve[3*i+1];
|
||||||
|
|
||||||
cairo_user_to_device(ctx, &x, &y);
|
cairo_user_to_device(C, &x, &y);
|
||||||
|
|
||||||
if(-x < G.width && x < 3*G.width && -y < G.height && y < 3*G.height) {
|
if(-x < ctx->width && x < 3*ctx->width && -y < ctx->height && y < 3*ctx->height) {
|
||||||
if(!last_inside) {
|
if(!last_inside) {
|
||||||
cairo_move_to(ctx, limit_curve[3*i], limit_curve[3*i+1]);
|
cairo_move_to(C, limit_curve[3*i], limit_curve[3*i+1]);
|
||||||
} else {
|
} else {
|
||||||
cairo_line_to(ctx, limit_curve[3*i], limit_curve[3*i+1]);
|
cairo_line_to(C, limit_curve[3*i], limit_curve[3*i+1]);
|
||||||
}
|
}
|
||||||
last_inside = 1;
|
last_inside = 1;
|
||||||
} else {
|
} else {
|
||||||
@ -447,8 +399,8 @@ void draw(cairo_t *ctx, void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_set_source_rgb(ctx, 0, 0, 0);
|
cairo_set_source_rgb(C, 0, 0, 0);
|
||||||
cairo_stroke(ctx);
|
cairo_stroke(C);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(show_boxes)
|
if(show_boxes)
|
||||||
@ -456,57 +408,189 @@ void draw(cairo_t *ctx, void *data)
|
|||||||
|
|
||||||
if(show_attractors)
|
if(show_attractors)
|
||||||
drawAttractors(ctx);
|
drawAttractors(ctx);
|
||||||
|
|
||||||
|
if(show_reflectors)
|
||||||
|
drawReflectors(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_identity_matrix(ctx);
|
cairo_identity_matrix(C);
|
||||||
|
|
||||||
cairo_move_to(ctx, 15, 30);
|
cairo_move_to(C, 15, 30);
|
||||||
cairo_set_source_rgb(ctx, 0, 0, 0);
|
cairo_set_source_rgb(C, 0, 0, 0);
|
||||||
char buf[100];
|
char buf[100];
|
||||||
sprintf(buf, "t = %.8f", parameter);
|
sprintf(buf, "t = %.8f", parameter);
|
||||||
cairo_show_text(ctx, buf);
|
cairo_show_text(C, buf);
|
||||||
|
|
||||||
cairo_pop_group_to_source(ctx);
|
cairo_pop_group_to_source(C);
|
||||||
cairo_paint(ctx);
|
cairo_paint(C);
|
||||||
cairo_surface_flush(cairo_get_target(ctx));
|
cairo_surface_flush(cairo_get_target(C));
|
||||||
|
|
||||||
gettimeofday(¤t_time, 0);
|
gettimeofday(¤t_time, 0);
|
||||||
double end_time = current_time.tv_sec + current_time.tv_usec*1e-6;
|
double end_time = current_time.tv_sec + current_time.tv_usec*1e-6;
|
||||||
printf("draw() finished in %g seconds\n", end_time - start_time);
|
printf("draw() finished in %g seconds\n", end_time - start_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
n_group_elements = 100000;
|
||||||
|
limit_curve = malloc(3*n_group_elements*sizeof(double));
|
||||||
|
group = malloc(n_group_elements*sizeof(groupelement_t));
|
||||||
|
ws = workspace_alloc(3);
|
||||||
|
|
||||||
|
LOOP(i) gen[i] = gsl_matrix_alloc(3, 3);
|
||||||
|
matrices = malloc(n_group_elements*sizeof(gsl_matrix*));
|
||||||
|
for(int i = 0; i < n_group_elements; i++)
|
||||||
|
matrices[i] = gsl_matrix_alloc(3, 3);
|
||||||
|
cartan = gsl_matrix_alloc(3, 3);
|
||||||
|
cob = gsl_matrix_alloc(3, 3);
|
||||||
|
coxeter = gsl_matrix_alloc(3, 3);
|
||||||
|
coxeter_fixedpoints = gsl_matrix_alloc(3, 3);
|
||||||
|
fixedpoints = gsl_matrix_alloc(3, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy()
|
||||||
|
{
|
||||||
|
free(limit_curve);
|
||||||
|
free(group);
|
||||||
|
workspace_free(ws);
|
||||||
|
|
||||||
|
LOOP(i) gsl_matrix_free(gen[i]);
|
||||||
|
for(int i = 0; i < n_group_elements; i++)
|
||||||
|
gsl_matrix_free(matrices[i]);
|
||||||
|
free(matrices);
|
||||||
|
gsl_matrix_free(cartan);
|
||||||
|
gsl_matrix_free(cob);
|
||||||
|
gsl_matrix_free(coxeter);
|
||||||
|
gsl_matrix_free(coxeter_fixedpoints);
|
||||||
|
gsl_matrix_free(fixedpoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print(DrawingContext *screen)
|
||||||
|
{
|
||||||
|
DrawingContext file;
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
|
||||||
|
char filename[100];
|
||||||
|
time_t t = time(NULL);
|
||||||
|
strftime(filename, sizeof(filename), "screenshot_%Y%m%d_%H%M%S.pdf", localtime(&t));
|
||||||
|
|
||||||
|
file.width = screen->width;
|
||||||
|
file.height = screen->width / sqrt(2.0);
|
||||||
|
file.matrix = screen->matrix;
|
||||||
|
file.matrix.y0 += (file.height - screen->height) / 2.0; // recenter vertically
|
||||||
|
|
||||||
|
surface = cairo_pdf_surface_create(filename, (double)file.width, (double)file.height);
|
||||||
|
file.cairo = cairo_create(surface);
|
||||||
|
|
||||||
|
draw(&file);
|
||||||
|
|
||||||
|
cairo_destroy(file.cairo);
|
||||||
|
cairo_surface_destroy(surface);
|
||||||
|
|
||||||
|
printf("Wrote sceenshot to file: %s\n", filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
int processEvent(GraphicsInfo *info, XEvent *ev)
|
||||||
|
{
|
||||||
|
int state;
|
||||||
|
unsigned long key;
|
||||||
|
|
||||||
|
switch(ev->type) {
|
||||||
|
|
||||||
|
case KeyPress:
|
||||||
|
state = ev->xkey.state & (ShiftMask | LockMask | ControlMask);
|
||||||
|
key = XkbKeycodeToKeysym(ev->xkey.display, ev->xkey.keycode, 0, !!(state & ShiftMask));
|
||||||
|
printf("Key pressed: %ld\n", key);
|
||||||
|
|
||||||
|
switch(key) {
|
||||||
|
case '<':
|
||||||
|
parameter /= exp(0.002);
|
||||||
|
limit_curve_valid = computeLimitCurve();
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
parameter *= exp(0.002);
|
||||||
|
limit_curve_valid = computeLimitCurve();
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
parameter = 2.890053638;
|
||||||
|
limit_curve_valid = computeLimitCurve();
|
||||||
|
break;
|
||||||
|
case XK_Return:
|
||||||
|
parameter = 2.76375163;
|
||||||
|
limit_curve_valid = computeLimitCurve();
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
printf("info->context->matrix.xx = %f;\n", info->context->matrix.xx);
|
||||||
|
printf("info->context->matrix.xy = %f;\n", info->context->matrix.xy);
|
||||||
|
printf("info->context->matrix.x0 = %f;\n", info->context->matrix.x0);
|
||||||
|
printf("info->context->matrix.yx = %f;\n", info->context->matrix.yx);
|
||||||
|
printf("info->context->matrix.yy = %f;\n", info->context->matrix.yy);
|
||||||
|
printf("info->context->matrix.y0 = %f;\n", info->context->matrix.y0);
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
show_boxes = !show_boxes;
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
show_attractors = !show_attractors;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
show_reflectors = !show_reflectors;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
show_limit = !show_limit;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
print(info->context);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
draw(info->context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
GraphicsInfo *info;
|
||||||
|
|
||||||
parameter = 3.0;
|
parameter = 3.0;
|
||||||
|
|
||||||
setup();
|
setup();
|
||||||
limit_curve_valid = computeLimitCurve();
|
limit_curve_valid = computeLimitCurve();
|
||||||
|
|
||||||
if(!initCairo(0, KeyPressMask, 200, 200, "Triangle group", &G))
|
info = initCairo(0, KeyPressMask, 200, 200, "Triangle group");
|
||||||
|
if(!info)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
DrawingContext *ctx = info->context;
|
||||||
|
|
||||||
|
|
||||||
|
ctx->matrix.xx = 837.930824;
|
||||||
|
ctx->matrix.xy = -712.651341;
|
||||||
|
ctx->matrix.x0 = 180.427716;
|
||||||
|
ctx->matrix.yx = 712.651341;
|
||||||
|
ctx->matrix.yy = 837.930824;
|
||||||
|
ctx->matrix.y0 = 1412.553240;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
cairo_matrix_init_identity(&G.matrix);
|
info->context->matrix.xx = 1636.583641;
|
||||||
G.matrix.xx = G.matrix.yy = G.scalefactor = 1100.0;
|
info->context->matrix.xy = -1391.897150;
|
||||||
G.matrix.x0 = 1150.0;
|
info->context->matrix.x0 = 975.772883;
|
||||||
G.matrix.y0 = 900.0;
|
info->context->matrix.yx = 1391.897150;
|
||||||
|
info->context->matrix.yy = 1636.583641;
|
||||||
|
info->context->matrix.y0 = 2446.174297;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
G.matrix.xx = 837.930824;
|
updateDimensions(ctx);
|
||||||
G.matrix.xy = -712.651341;
|
|
||||||
G.matrix.x0 = 180.427716;
|
|
||||||
G.matrix.yx = 712.651341;
|
|
||||||
G.matrix.yy = 837.930824;
|
|
||||||
G.matrix.y0 = 1412.553240;
|
|
||||||
G.scalefactor = 1100.000000;
|
|
||||||
|
|
||||||
startTimer(&G);
|
startTimer(info);
|
||||||
|
|
||||||
while(!checkEvents(&G, processEvent, draw, 0)) {
|
while(!checkEvents(info, processEvent, draw)) {
|
||||||
waitUpdateTimer(&G);
|
waitUpdateTimer(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
destroyCairo(&G);
|
destroyCairo(info);
|
||||||
|
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user