boxes, attractors and everything

This commit is contained in:
Florian Stecker
2018-08-17 15:41:17 +02:00
parent 09a43c7ac3
commit c3deff6d64
3 changed files with 391 additions and 277 deletions

View File

@@ -1,6 +1,8 @@
#include <math.h>
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <cairo/cairo-pdf.h>
#include <X11/XKBlib.h>
#include "initcairo.h"
@@ -14,19 +16,27 @@ typedef struct {
double y;
} 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 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 computeLimitCurve();
void draw(cairo_t *ctx, void *data);
point_t intersect(point_t a, point_t b, point_t c, point_t d);
void drawBoxStd(cairo_t *ctx, const char *word, char base);
void drawBox(cairo_t *ctx, const char *word1, const char *word2);
GraphicsInfo G;
void drawBoxes(DrawingContext *ctx);
void drawReflectors(DrawingContext *ctx);
void drawAttractors(DrawingContext *ctx);
void draw(DrawingContext *ctx);
void setup();
void destroy();
void print(DrawingContext *screen);
int processEvent(GraphicsInfo *info, XEvent *ev);
double parameter;
int n_group_elements;
@@ -40,97 +50,9 @@ gsl_matrix *cartan, *cob, *coxeter, *coxeter_fixedpoints, *fixedpoints;
int show_boxes = 0;
int show_attractors = 0;
int show_reflectors = 0;
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)
{
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);
}
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
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;
}
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
cairo_save(ctx);
cairo_move_to(ctx, p.x, p.y);
cairo_close_path(ctx);
cairo_set_line_cap(ctx, CAIRO_LINE_CAP_ROUND);
cairo_set_line_width(ctx, 10.0/G.scalefactor);
cairo_stroke(ctx);
cairo_restore(ctx);
point_t c, xplus, xminus;
double normb;
double scalbc;
c.x = ctx->center_x;
c.y = ctx->center_y;
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
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)
{
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
void drawPolygon(DrawingContext *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, 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);
}
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];
@@ -227,7 +185,7 @@ void drawAttractorConnection(cairo_t *ctx, const char *word1, const char *word2)
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];
@@ -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]);
}
void drawBoxStd(cairo_t *ctx, const char *word, char base)
void drawBoxStd(DrawingContext *ctx, const char *word, char base)
{
char word1[100];
char word2[100];
@@ -265,6 +223,11 @@ void drawBoxStd(cairo_t *ctx, const char *word, char base)
drawBox(ctx, word1, word2);
}
int compareAngle(const void *x, const void *y)
{
return ((double*)x)[2] > ((double*)y)[2] ? 1 : -1;
}
int computeLimitCurve()
{
int p = 5, q = 5, r = 5;
@@ -314,85 +277,65 @@ int computeLimitCurve()
return 1;
}
void drawBoxes(cairo_t *ctx)
void drawBoxes(DrawingContext *ctx)
{
cairo_set_source_rgb(ctx, 1, 0, 0);
drawBoxStd(ctx, "c", 'C');
drawBoxStd(ctx, "", 'B');
drawBoxStd(ctx, "a", 'A');
drawBoxStd(ctx, "", 'C');
// drawBoxStd(ctx, "", 'A');
drawBoxStd(ctx, "b", 'B');
cairo_t *C = ctx->cairo;
cairo_set_source_rgb(ctx, 0, 0, 1);
drawBoxStd(ctx, "ca", 'A');
drawBoxStd(ctx, "cac", 'C');
drawBoxStd(ctx, "caca", 'A');
// drawBoxStd(ctx, "cacac", 'C');
// drawBoxStd(ctx, "acac", 'A');
// drawBoxStd(ctx, "aca", 'C');
/*
cairo_set_source_rgb(C, 1, 0, 0);
drawBoxStd(ctx, "c", 'C');
drawBoxStd(ctx, "", 'B');
drawBoxStd(ctx, "a", 'A');
drawBoxStd(ctx, "", 'C');
drawBoxStd(ctx, "b", 'B');
*/
cairo_set_source_rgb(ctx, 0, 1, 0);
drawBoxStd(ctx, "ac", 'C');
// drawBoxStd(ctx, "aca", 'A');
drawBoxStd(ctx, "acac", 'C');
// drawBoxStd(ctx, "acaca", 'A');
// drawBoxStd(ctx, "caca", 'C');
// drawBoxStd(ctx, "cac", 'A');
cairo_set_source_rgb(C, 0, 0, 0);
drawBoxStd(ctx, "ca", 'A');
drawBoxStd(ctx, "cac", 'C');
drawBoxStd(ctx, "caca", 'A');
drawBoxStd(ctx, "acac", 'C');
drawBoxStd(ctx, "aca", 'A');
drawBoxStd(ctx, "ac", 'C');
cairo_set_source_rgb(ctx, 1, 0, 1);
drawBoxStd(ctx, "aca cb", 'B');
drawBoxStd(ctx, "aca cbc", 'C');
drawBoxStd(ctx, "aca cbcb", 'B');
drawBoxStd(ctx, "aca bcbc", 'C');
drawBoxStd(ctx, "aca bcb", 'B');
drawBoxStd(ctx, "aca bc", 'C');
cairo_set_source_rgb(C, 1, 0, 1);
/*
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");
/*
drawBoxStd(ctx, "aca cb", 'B');
drawBoxStd(ctx, "aca cbc", 'C');
drawBoxStd(ctx, "aca cbcb", 'B');
drawBoxStd(ctx, "aca bcbc", 'C');
drawBoxStd(ctx, "aca bcb", 'B');
drawBoxStd(ctx, "aca bc", 'C');
*/
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];
@@ -400,30 +343,39 @@ void drawAttractors(cairo_t *ctx)
fixedPoints("bca", p[1]);
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]);
drawPoint(ctx, p[i][j]);
}
LOOP(i) LOOP(j) drawLine(ctx, p[i][j], p[i][(j+1)%3]);
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(cairo_t *ctx, void *data)
void draw(DrawingContext *ctx)
{
struct timeval current_time;
gettimeofday(&current_time, 0);
double start_time = current_time.tv_sec + current_time.tv_usec*1e-6;
cairo_push_group(ctx);
cairo_set_source_rgb(ctx, 1, 1, 1);
cairo_paint(ctx);
cairo_t *C = ctx->cairo;
updateDimensions(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
cairo_set_line_width(ctx, 1.0/G.scalefactor);
cairo_set_font_size(ctx, 16);
cairo_set_line_join(ctx, CAIRO_LINE_JOIN_BEVEL);
cairo_set_line_cap(ctx, CAIRO_LINE_CAP_ROUND);
cairo_set_line_width(C, 1.0/ctx->scalefactor);
cairo_set_font_size(C, 16);
cairo_set_line_join(C, CAIRO_LINE_JOIN_BEVEL);
cairo_set_line_cap(C, CAIRO_LINE_CAP_ROUND);
if(limit_curve_valid) {
@@ -433,13 +385,13 @@ void draw(cairo_t *ctx, void *data)
double x = limit_curve[3*i];
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) {
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 {
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;
} else {
@@ -447,8 +399,8 @@ void draw(cairo_t *ctx, void *data)
}
}
cairo_set_source_rgb(ctx, 0, 0, 0);
cairo_stroke(ctx);
cairo_set_source_rgb(C, 0, 0, 0);
cairo_stroke(C);
}
if(show_boxes)
@@ -456,57 +408,189 @@ void draw(cairo_t *ctx, void *data)
if(show_attractors)
drawAttractors(ctx);
if(show_reflectors)
drawReflectors(ctx);
}
cairo_identity_matrix(ctx);
cairo_identity_matrix(C);
cairo_move_to(ctx, 15, 30);
cairo_set_source_rgb(ctx, 0, 0, 0);
cairo_move_to(C, 15, 30);
cairo_set_source_rgb(C, 0, 0, 0);
char buf[100];
sprintf(buf, "t = %.8f", parameter);
cairo_show_text(ctx, buf);
cairo_show_text(C, buf);
cairo_pop_group_to_source(ctx);
cairo_paint(ctx);
cairo_surface_flush(cairo_get_target(ctx));
cairo_pop_group_to_source(C);
cairo_paint(C);
cairo_surface_flush(cairo_get_target(C));
gettimeofday(&current_time, 0);
double end_time = current_time.tv_sec + current_time.tv_usec*1e-6;
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()
{
GraphicsInfo *info;
parameter = 3.0;
setup();
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;
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);
G.matrix.xx = G.matrix.yy = G.scalefactor = 1100.0;
G.matrix.x0 = 1150.0;
G.matrix.y0 = 900.0;
info->context->matrix.xx = 1636.583641;
info->context->matrix.xy = -1391.897150;
info->context->matrix.x0 = 975.772883;
info->context->matrix.yx = 1391.897150;
info->context->matrix.yy = 1636.583641;
info->context->matrix.y0 = 2446.174297;
*/
G.matrix.xx = 837.930824;
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;
updateDimensions(ctx);
startTimer(&G);
startTimer(info);
while(!checkEvents(&G, processEvent, draw, 0)) {
waitUpdateTimer(&G);
while(!checkEvents(info, processEvent, draw)) {
waitUpdateTimer(info);
}
destroyCairo(&G);
destroyCairo(info);
destroy();