movie command line arguments

This commit is contained in:
Florian Stecker 2023-02-05 15:10:16 -05:00
parent a8b4bb7c2c
commit 78769593a7
2 changed files with 379 additions and 362 deletions

737
main.c
View File

@ -11,461 +11,474 @@
#include "linalg.h" #include "linalg.h"
#define TOGGLE(a) do { (a) = !(a); } while(0) #define TOGGLE(a) do { (a) = !(a); } while(0)
#define SIGN(x) ((x) > 0 ? 1.0 : -1.0)
DrawingContext *screen_context; DrawingContext *screen_context;
// setup everything except cairo and dim, which will be provided by the graphics system // setup everything except cairo and dim, which will be provided by the graphics system
void setupContext(DrawingContext *ctx, int argc, char *argv[]) void setupContext(DrawingContext *ctx, int argc, char *argv[])
{ {
ctx->n_group_elements = NUM_GROUP_ELEMENTS; ctx->n_group_elements = NUM_GROUP_ELEMENTS;
ctx->n_group_elements_combinatorial = NUM_GROUP_ELEMENTS_COMBINATORIAL; ctx->n_group_elements_combinatorial = NUM_GROUP_ELEMENTS_COMBINATORIAL;
ctx->p[0] = atoi(argv[1]); ctx->p[0] = atoi(argv[1]);
ctx->p[1] = atoi(argv[2]); ctx->p[1] = atoi(argv[2]);
ctx->p[2] = atoi(argv[3]); ctx->p[2] = atoi(argv[3]);
ctx->k[0] = atoi(argv[4]); ctx->k[0] = atoi(argv[4]);
ctx->k[1] = atoi(argv[5]); ctx->k[1] = atoi(argv[5]);
ctx->k[2] = atoi(argv[6]); ctx->k[2] = atoi(argv[6]);
if(argc > 7) if(argc > 7)
ctx->parameter = atof(argv[7]); ctx->parameter = atof(argv[7]);
else else
ctx->parameter = 1.0; ctx->parameter = 1.0;
if(argc > 8) if(argc > 8)
ctx->parameter2 = atof(argv[8]); ctx->parameter2 = atof(argv[8]);
else else
ctx->parameter2 = 1.0; ctx->parameter2 = 1.0;
// ctx->parameter = 2.77; if(argc > 12) {
// ctx->parameter = 0.1; ctx->movie_filename = argv[9];
ctx->show_boxes = 0; ctx->movie_parameter_duration = atof(argv[10]);
ctx->show_boxes2 = 0; ctx->movie_parameter2_duration = atof(argv[11]);
ctx->show_attractors = 0; ctx->movie_n_frames = atoi(argv[12]);
ctx->show_reflectors = 0; } else {
ctx->show_rotated_reflectors = 0; ctx->movie_n_frames = 0;
ctx->show_limit = 0; }
ctx->show_dual_limit = 0; // ctx->parameter = 2.77;
ctx->show_text = 1; // ctx->parameter = 0.1;
ctx->mode = 0; ctx->show_boxes = 0;
ctx->use_rotation_basis = 2; ctx->show_boxes2 = 0;
ctx->limit_with_lines = 0; ctx->show_attractors = 0;
ctx->use_repelling = 0; ctx->show_reflectors = 0;
ctx->show_marking = 1; ctx->show_rotated_reflectors = 0;
ctx->marking.x = -0.73679; ctx->show_limit = 0;
ctx->marking.y = -0.01873; ctx->show_dual_limit = 0;
ctx->show_coxeter_orbit = 0; ctx->show_text = 1;
ctx->mode = 0;
ctx->use_rotation_basis = 1;
ctx->limit_with_lines = 0;
ctx->use_repelling = 0;
ctx->show_marking = 0;
ctx->marking.x = -0.73679;
ctx->marking.y = -0.01873;
ctx->show_coxeter_orbit = 0;
ctx->limit_curve = malloc(3*ctx->n_group_elements*sizeof(double)); ctx->limit_curve = malloc(3*ctx->n_group_elements*sizeof(double));
ctx->limit_curve_count = -1; ctx->limit_curve_count = -1;
ctx->group = malloc(ctx->n_group_elements_combinatorial*sizeof(groupelement_t)); ctx->group = malloc(ctx->n_group_elements_combinatorial*sizeof(groupelement_t));
generate_triangle_group(ctx->group, ctx->n_group_elements_combinatorial, ctx->p[0], ctx->p[1], ctx->p[2]); generate_triangle_group(ctx->group, ctx->n_group_elements_combinatorial, ctx->p[0], ctx->p[1], ctx->p[2]);
// the temporary stuff // the temporary stuff
ctx->cartan = gsl_matrix_alloc(3, 3); ctx->cartan = gsl_matrix_alloc(3, 3);
ctx->cob = gsl_matrix_alloc(3, 3); ctx->cob = gsl_matrix_alloc(3, 3);
ctx->ws = workspace_alloc(3); ctx->ws = workspace_alloc(3);
} }
void destroyContext(DrawingContext *ctx) void destroyContext(DrawingContext *ctx)
{ {
free(ctx->limit_curve); free(ctx->limit_curve);
free(ctx->group); free(ctx->group);
gsl_matrix_free(ctx->cartan); gsl_matrix_free(ctx->cartan);
gsl_matrix_free(ctx->cob); gsl_matrix_free(ctx->cob);
workspace_free(ctx->ws); workspace_free(ctx->ws);
} }
void computeMatrix(DrawingContext *ctx, gsl_matrix *result, const char *type) void computeMatrix(DrawingContext *ctx, gsl_matrix *result, const char *type)
{ {
gsl_matrix **gen = getTempMatrices(ctx->ws, 6); gsl_matrix **gen = getTempMatrices(ctx->ws, 6);
// ERROR(strlen(type) != 2, "Invalid call of computeRotationMatrix()\n"); // ERROR(strlen(type) != 2, "Invalid call of computeRotationMatrix()\n");
initializeTriangleGeneratorsCurrent(gen, ctx); initializeTriangleGeneratorsCurrent(gen, ctx);
gsl_matrix_set_identity(result); gsl_matrix_set_identity(result);
for(int i = 0; i < strlen(type); i++) { for(int i = 0; i < strlen(type); i++) {
if(type[i] >= 'a' && type[i] <= 'c') if(type[i] >= 'a' && type[i] <= 'c')
multiply_right(result, gen[type[i]-'a'], ctx->ws); multiply_right(result, gen[type[i]-'a'], ctx->ws);
else if(type[i] >= 'A' && type[i] <= 'C') else if(type[i] >= 'A' && type[i] <= 'C')
multiply_right(result, gen[type[i]-'A'+3], ctx->ws); multiply_right(result, gen[type[i]-'A'+3], ctx->ws);
} }
releaseTempMatrices(ctx->ws, 6); releaseTempMatrices(ctx->ws, 6);
} }
void computeRotationMatrixFrame(DrawingContext *ctx, gsl_matrix *result, const char *type) void computeRotationMatrixFrame(DrawingContext *ctx, gsl_matrix *result, const char *type)
{ {
gsl_matrix *tmp = getTempMatrix(ctx->ws); gsl_matrix *tmp = getTempMatrix(ctx->ws);
computeMatrix(ctx, tmp, type); computeMatrix(ctx, tmp, type);
rotation_frame(tmp, result, ctx->ws); rotation_frame(tmp, result, ctx->ws);
releaseTempMatrices(ctx->ws, 1); releaseTempMatrices(ctx->ws, 1);
} }
void computeBoxTransform(DrawingContext *ctx, char *word1, char *word2, gsl_matrix *result) void computeBoxTransform(DrawingContext *ctx, char *word1, char *word2, gsl_matrix *result)
{ {
vector_t p[2][3],i[2]; vector_t p[2][3],i[2];
vector_t std[4] = { vector_t std[4] = {
{-1, -1, 1}, {-1, -1, 1},
{-1, 1, 1}, {-1, 1, 1},
{1, 1, 1}, {1, 1, 1},
{1, -1, 1} {1, -1, 1}
}; };
gsl_vector **vertices = getTempVectors(ctx->ws, 4); gsl_vector **vertices = getTempVectors(ctx->ws, 4);
gsl_vector **std_vertices = getTempVectors(ctx->ws, 4); gsl_vector **std_vertices = getTempVectors(ctx->ws, 4);
gsl_matrix *tmp = getTempMatrix(ctx->ws); gsl_matrix *tmp = getTempMatrix(ctx->ws);
gsl_matrix *to_frame = getTempMatrix(ctx->ws); gsl_matrix *to_frame = getTempMatrix(ctx->ws);
gsl_matrix *to_std_frame = getTempMatrix(ctx->ws); gsl_matrix *to_std_frame = getTempMatrix(ctx->ws);
fixedPoints(ctx, word1, p[0]); fixedPoints(ctx, word1, p[0]);
fixedPoints(ctx, word2, p[1]); fixedPoints(ctx, word2, p[1]);
// intersect attracting line with neutral line of the other element // intersect attracting line with neutral line of the other element
for(int j = 0; j < 2; j++) for(int j = 0; j < 2; j++)
i[j] = cross(cross(p[j%2][0],p[j%2][1]),cross(p[(j+1)%2][0],p[(j+1)%2][2])); i[j] = cross(cross(p[j%2][0],p[j%2][1]),cross(p[(j+1)%2][0],p[(j+1)%2][2]));
// box consists of p[0][0], i[0], p[1][0], i[1] // box consists of p[0][0], i[0], p[1][0], i[1]
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
vectorToGsl(std[i], std_vertices[i]); vectorToGsl(std[i], std_vertices[i]);
vectorToGsl(p[0][0], vertices[0]); vectorToGsl(p[0][0], vertices[0]);
vectorToGsl(i[0], vertices[1]); vectorToGsl(i[0], vertices[1]);
vectorToGsl(p[1][0], vertices[2]); vectorToGsl(p[1][0], vertices[2]);
vectorToGsl(i[1], vertices[3]); vectorToGsl(i[1], vertices[3]);
projective_frame(std_vertices, to_std_frame, ctx->ws); projective_frame(std_vertices, to_std_frame, ctx->ws);
projective_frame(vertices, to_frame, ctx->ws); projective_frame(vertices, to_frame, ctx->ws);
invert(to_frame, tmp, ctx->ws); invert(to_frame, tmp, ctx->ws);
multiply(to_std_frame, tmp, result); multiply(to_std_frame, tmp, result);
/* /*
LOOP(i) { LOOP(i) {
LOOP(j) { LOOP(j) {
printf("%.4f ", gsl_matrix_get(result, i, j)); printf("%.4f ", gsl_matrix_get(result, i, j));
} }
printf("\n"); printf("\n");
}*/ }*/
releaseTempVectors(ctx->ws, 8); releaseTempVectors(ctx->ws, 8);
releaseTempMatrices(ctx->ws, 3); releaseTempMatrices(ctx->ws, 3);
} }
void updateMatrices(DrawingContext *ctx) void updateMatrices(DrawingContext *ctx)
{ {
double angle[3]; double angle[3];
LOOP(i) angle[i] = M_PI*ctx->k[i]/ctx->p[i]; LOOP(i) angle[i] = M_PI*ctx->k[i]/ctx->p[i];
cartanMatrix(ctx->cartan, angle[0], angle[1], angle[2], ctx->parameter); cartanMatrix(ctx->cartan, angle[0], angle[1], angle[2], ctx->parameter);
gsl_matrix *tmp = getTempMatrix(ctx->ws); gsl_matrix *tmp = getTempMatrix(ctx->ws);
int nmodes = 5;
if(ctx->use_rotation_basis % 5 == 0) { if(ctx->use_rotation_basis % nmodes == 0) {
gsl_matrix_set(tmp, 0, 0, 0.0); gsl_matrix_set(tmp, 0, 0, 0.0);
gsl_matrix_set(tmp, 0, 1, sqrt(3.0)/2.0); gsl_matrix_set(tmp, 0, 1, sqrt(3.0)/2.0);
gsl_matrix_set(tmp, 0, 2, -sqrt(3.0)/2.0); gsl_matrix_set(tmp, 0, 2, -sqrt(3.0)/2.0);
gsl_matrix_set(tmp, 1, 0, 1.0); gsl_matrix_set(tmp, 1, 0, 1.0);
gsl_matrix_set(tmp, 1, 1, -0.5); gsl_matrix_set(tmp, 1, 1, -0.5);
gsl_matrix_set(tmp, 1, 2, -0.5); gsl_matrix_set(tmp, 1, 2, -0.5);
gsl_matrix_set(tmp, 2, 0, 1.0); gsl_matrix_set(tmp, 2, 0, 1.0);
gsl_matrix_set(tmp, 2, 1, 1.0); gsl_matrix_set(tmp, 2, 1, 1.0);
gsl_matrix_set(tmp, 2, 2, 1.0); gsl_matrix_set(tmp, 2, 2, 1.0);
gsl_matrix_memcpy(ctx->cob, tmp); gsl_matrix_memcpy(ctx->cob, tmp);
} else if(ctx->use_rotation_basis % 5 == 1) { } else if(ctx->use_rotation_basis % nmodes == 1) {
gsl_matrix_memcpy(ctx->cob, ctx->cartan); // is this a good choice of basis for any reason? gsl_matrix_set(tmp, 0, 0, 1.0);
} else if(ctx->use_rotation_basis % 5 == 2) { gsl_matrix_set(tmp, 0, 1, -1.0);
computeRotationMatrixFrame(ctx, tmp, "C"); gsl_matrix_set(tmp, 0, 2, 0.0);
invert(tmp, ctx->cob, ctx->ws); gsl_matrix_set(tmp, 1, 0, 1.0);
} else if(ctx->use_rotation_basis % 5 == 3) { gsl_matrix_set(tmp, 1, 1, 1.0);
computeBoxTransform(ctx, "acb", "cba", ctx->cob); gsl_matrix_set(tmp, 1, 2, 0.0);
// computeBoxTransform(ctx, "cab", "bca", ctx->cob); gsl_matrix_set(tmp, 2, 0, 0.0);
// computeBoxTransform(ctx, "acb", "cba", ctx->cob); gsl_matrix_set(tmp, 2, 1, 0.0);
} else { gsl_matrix_set(tmp, 2, 2, 1.0);
cartanMatrix(tmp, M_PI/ctx->p[0], M_PI/ctx->p[1], M_PI/ctx->p[2], 1.0); gsl_matrix_memcpy(ctx->cob, ctx->cartan); // is this a good choice of basis for any reason?
diagonalize_symmetric_form(tmp, ctx->cob, ctx->ws); multiply_left(tmp, ctx->cob, ctx->ws);
} } else if(ctx->use_rotation_basis % nmodes == 2) {
computeRotationMatrixFrame(ctx, tmp, "C");
invert(tmp, ctx->cob, ctx->ws);
} else if(ctx->use_rotation_basis % nmodes == 3) {
computeBoxTransform(ctx, "acb", "cba", ctx->cob);
// computeBoxTransform(ctx, "cab", "bca", ctx->cob);
// computeBoxTransform(ctx, "acb", "cba", ctx->cob);
} else {
cartanMatrix(tmp, M_PI/ctx->p[0], M_PI/ctx->p[1], M_PI/ctx->p[2], 1.0);
diagonalize_symmetric_form(tmp, ctx->cob, ctx->ws);
}
releaseTempMatrices(ctx->ws, 1); releaseTempMatrices(ctx->ws, 1);
} }
void output_info(DrawingContext *ctx) void output_info(DrawingContext *ctx)
{ {
vector_t p[4][3]; vector_t p[4][3];
point_t pt; point_t pt;
fixedPoints(ctx, "abc", p[0]); fixedPoints(ctx, "abc", p[0]);
fixedPoints(ctx, "bca", p[1]); fixedPoints(ctx, "bca", p[1]);
fixedPoints(ctx, "cab", p[2]); fixedPoints(ctx, "cab", p[2]);
pt = vectorToPoint(ctx, p[0][0]); pt = vectorToPoint(ctx, p[0][0]);
printf("(abc)-+ = (%f %f)\n", pt.x, pt.y); printf("(abc)-+ = (%f %f)\n", pt.x, pt.y);
pt = vectorToPoint(ctx, p[1][0]); pt = vectorToPoint(ctx, p[1][0]);
printf("(bca)-+ = (%f %f)\n", pt.x, pt.y); printf("(bca)-+ = (%f %f)\n", pt.x, pt.y);
} }
void print(DrawingContext *screen) void print(DrawingContext *screen)
{ {
DrawingContext file; DrawingContext file;
DimensionsInfo dim; DimensionsInfo dim;
cairo_surface_t *surface; cairo_surface_t *surface;
char filename[100]; char filename[100];
time_t t = time(NULL); time_t t = time(NULL);
strftime(filename, sizeof(filename), "screenshot_%Y%m%d_%H%M%S.pdf", localtime(&t)); strftime(filename, sizeof(filename), "screenshot_%Y%m%d_%H%M%S.pdf", localtime(&t));
memcpy(&file, screen, sizeof(file)); memcpy(&file, screen, sizeof(file));
dim.width = screen->dim->width; dim.width = screen->dim->width;
dim.height = screen->dim->width / sqrt(2.0); dim.height = screen->dim->width / sqrt(2.0);
dim.matrix = screen->dim->matrix; dim.matrix = screen->dim->matrix;
dim.matrix.y0 += ((double)dim.height - (double)screen->dim->height) / 2.0; // recenter vertically dim.matrix.y0 += ((double)dim.height - (double)screen->dim->height) / 2.0; // recenter vertically
updateDimensions(&dim); updateDimensions(&dim);
file.dim = &dim; file.dim = &dim;
surface = cairo_pdf_surface_create(filename, (double)dim.width, (double)dim.height); surface = cairo_pdf_surface_create(filename, (double)dim.width, (double)dim.height);
file.cairo = cairo_create(surface); file.cairo = cairo_create(surface);
draw(&file); draw(&file);
cairo_destroy(file.cairo); cairo_destroy(file.cairo);
cairo_surface_destroy(surface); cairo_surface_destroy(surface);
printf("Wrote sceenshot to file: %s\n", filename); printf("Wrote sceenshot to file: %s\n", filename);
} }
int processEvent(GraphicsInfo *info, XEvent *ev) int processEvent(GraphicsInfo *info, XEvent *ev)
{ {
int state; int state;
unsigned long key; unsigned long key;
char filename[100]; char filename[100];
// fprintf(stderr, "Event: %d\n", ev->type); // fprintf(stderr, "Event: %d\n", ev->type);
switch(ev->type) { switch(ev->type) {
case ButtonPress: case ButtonPress:
state = ev->xbutton.state & (ShiftMask | LockMask | ControlMask); state = ev->xbutton.state & (ShiftMask | LockMask | ControlMask);
if(ev->xbutton.button == 1 && state & ShiftMask) { if(ev->xbutton.button == 1 && state & ShiftMask) {
screen_context->marking.x = (double)ev->xbutton.x; screen_context->marking.x = (double)ev->xbutton.x;
screen_context->marking.y = (double)ev->xbutton.y; screen_context->marking.y = (double)ev->xbutton.y;
printf("mouse button pressed: %f, %f\n", screen_context->marking.x, screen_context->marking.y); printf("mouse button pressed: %f, %f\n", screen_context->marking.x, screen_context->marking.y);
cairo_set_matrix(screen_context->cairo, &screen_context->dim->matrix); cairo_set_matrix(screen_context->cairo, &screen_context->dim->matrix);
cairo_device_to_user(screen_context->cairo, &screen_context->marking.x, &screen_context->marking.y); cairo_device_to_user(screen_context->cairo, &screen_context->marking.x, &screen_context->marking.y);
printf("mouse button pressed transformed: %f, %f\n", screen_context->marking.x, screen_context->marking.y); printf("mouse button pressed transformed: %f, %f\n", screen_context->marking.x, screen_context->marking.y);
return STATUS_REDRAW; return STATUS_REDRAW;
} }
break; break;
case KeyPress: case KeyPress:
state = ev->xkey.state & (ShiftMask | LockMask | ControlMask); state = ev->xkey.state & (ShiftMask | LockMask | ControlMask);
key = XkbKeycodeToKeysym(ev->xkey.display, ev->xkey.keycode, 0, !!(state & ShiftMask)); key = XkbKeycodeToKeysym(ev->xkey.display, ev->xkey.keycode, 0, !!(state & ShiftMask));
printf("Key pressed: %ld\n", key); printf("Key pressed: %ld\n", key);
switch(key) { switch(key) {
case XK_Down: case XK_Down:
screen_context->parameter /= exp(0.002); if(ev->xkey.state & ShiftMask)
updateMatrices(screen_context); screen_context->parameter /= exp(0.00005);
computeLimitCurve(screen_context); else
break; screen_context->parameter /= exp(0.002);
case XK_Up: updateMatrices(screen_context);
screen_context->parameter *= exp(0.002); computeLimitCurve(screen_context);
updateMatrices(screen_context); break;
computeLimitCurve(screen_context); case XK_Up:
break; if(ev->xkey.state & ShiftMask)
case XK_Left: screen_context->parameter *= exp(0.00005);
screen_context->parameter2 /= exp(0.002); else
updateMatrices(screen_context); screen_context->parameter *= exp(0.002);
computeLimitCurve(screen_context); updateMatrices(screen_context);
break; computeLimitCurve(screen_context);
case XK_Right: break;
screen_context->parameter2 *= exp(0.002); case XK_Left:
updateMatrices(screen_context); if(ev->xkey.state & ShiftMask)
computeLimitCurve(screen_context); screen_context->parameter2 /= exp(0.00005);
break; else
case XK_Page_Down: screen_context->parameter2 /= exp(0.002);
screen_context->parameter /= exp(0.02); updateMatrices(screen_context);
updateMatrices(screen_context); computeLimitCurve(screen_context);
computeLimitCurve(screen_context); break;
break; case XK_Right:
case XK_Page_Up: if(ev->xkey.state & ShiftMask)
screen_context->parameter *= exp(0.02); screen_context->parameter2 *= exp(0.00005);
updateMatrices(screen_context); else
computeLimitCurve(screen_context); screen_context->parameter2 *= exp(0.002);
break; updateMatrices(screen_context);
case ' ': computeLimitCurve(screen_context);
screen_context->parameter = 5.57959706; break;
updateMatrices(screen_context); case XK_Page_Down:
computeLimitCurve(screen_context); screen_context->parameter /= exp(0.02);
break; updateMatrices(screen_context);
case XK_Return: computeLimitCurve(screen_context);
// screen_context->parameter = 2.76375163; break;
screen_context->parameter = 5.29063366; case XK_Page_Up:
updateMatrices(screen_context); screen_context->parameter *= exp(0.02);
computeLimitCurve(screen_context); updateMatrices(screen_context);
break; computeLimitCurve(screen_context);
case 'm': break;
printf("matrix.xx = %f;\n", info->dim->matrix.xx); case ' ':
printf("matrix.xy = %f;\n", info->dim->matrix.xy); screen_context->parameter = 5.57959706;
printf("matrix.x0 = %f;\n", info->dim->matrix.x0); updateMatrices(screen_context);
printf("matrix.yx = %f;\n", info->dim->matrix.yx); computeLimitCurve(screen_context);
printf("matrix.yy = %f;\n", info->dim->matrix.yy); break;
printf("matrix.y0 = %f;\n", info->dim->matrix.y0); case XK_Return:
break; // screen_context->parameter = 2.76375163;
case 'i': screen_context->parameter = 5.29063366;
output_info(screen_context); updateMatrices(screen_context);
break; computeLimitCurve(screen_context);
case 'b': break;
TOGGLE(screen_context->show_boxes); case 'm':
break; printf("matrix.xx = %f;\n", info->dim->matrix.xx);
case 'B': printf("matrix.xy = %f;\n", info->dim->matrix.xy);
TOGGLE(screen_context->show_boxes2); printf("matrix.x0 = %f;\n", info->dim->matrix.x0);
break; printf("matrix.yx = %f;\n", info->dim->matrix.yx);
case 'a': printf("matrix.yy = %f;\n", info->dim->matrix.yy);
TOGGLE(screen_context->show_attractors); printf("matrix.y0 = %f;\n", info->dim->matrix.y0);
break; break;
case 'r': case 'i':
TOGGLE(screen_context->show_reflectors); output_info(screen_context);
break; break;
case 'x': case 'b':
TOGGLE(screen_context->show_rotated_reflectors); TOGGLE(screen_context->show_boxes);
break; break;
case 'L': case 'B':
TOGGLE(screen_context->limit_with_lines); TOGGLE(screen_context->show_boxes2);
break; break;
case 'l': case 'a':
TOGGLE(screen_context->show_limit); TOGGLE(screen_context->show_attractors);
break; break;
case 'd': case 'r':
TOGGLE(screen_context->show_dual_limit); TOGGLE(screen_context->show_reflectors);
break; break;
case 'R': case 'x':
screen_context->use_rotation_basis++; TOGGLE(screen_context->show_rotated_reflectors);
updateMatrices(screen_context); break;
computeLimitCurve(screen_context); case 'L':
break; TOGGLE(screen_context->limit_with_lines);
case 'p': break;
print(screen_context); case 'l':
break; TOGGLE(screen_context->show_limit);
case 'M': break;
/* case 'd':
screen_context->limit_with_lines = 0; TOGGLE(screen_context->show_dual_limit);
double parameter_start = screen_context->parameter; break;
for(int i = 0; i <= 1300; i++) { case 'R':
if(i < 400) screen_context->use_rotation_basis++;
screen_context->parameter = exp(log(parameter_start)+0.002*i); updateMatrices(screen_context);
else if(i < 500) computeLimitCurve(screen_context);
screen_context->parameter = exp(log(parameter_start)+0.002*400); break;
else case 'p':
screen_context->parameter = exp(log(parameter_start)+0.002*(900-i)); print(screen_context);
updateMatrices(screen_context); break;
computeLimitCurve(screen_context); case 'M':
draw(screen_context); screen_context->limit_with_lines = 0;
sprintf(filename, "movie3/test%03d.png", i); double parameter_start = screen_context->parameter;
cairo_surface_write_to_png(info->buffer_surface, filename); double parameter2_start = screen_context->parameter2;
printf("Finished drawing %s\n", filename); for(int i = 0; i <= screen_context->movie_n_frames; i++) {
} screen_context->parameter = SIGN(parameter_start)*exp(log(fabs(parameter_start)) +
*/ i*screen_context->movie_parameter_duration/screen_context->movie_n_frames);
screen_context->limit_with_lines = 0; screen_context->parameter2 = SIGN(parameter2_start)*exp(log(fabs(parameter2_start)) +
double parameter_start = screen_context->parameter; i*screen_context->movie_parameter2_duration/screen_context->movie_n_frames);
for(int i = 0; i <= 1300; i++) { updateMatrices(screen_context);
if(i < 400) computeLimitCurve(screen_context);
screen_context->parameter = exp(0.003*i); draw(screen_context);
else if(i < 500) sprintf(filename, "output/%s%03d.png", screen_context->movie_filename, i);
screen_context->parameter = exp(0.003*400); cairo_surface_write_to_png(info->buffer_surface, filename);
else printf("Finished drawing %s\n", filename);
screen_context->parameter = exp(0.003*(900-i)); }
updateMatrices(screen_context);
computeLimitCurve(screen_context);
draw(screen_context);
sprintf(filename, "movie5/test%03d.png", i);
cairo_surface_write_to_png(info->buffer_surface, filename);
printf("Finished drawing %s\n", filename);
}
case 'f': case 'f':
TOGGLE(screen_context->use_repelling); TOGGLE(screen_context->use_repelling);
computeLimitCurve(screen_context); computeLimitCurve(screen_context);
break; break;
case 't': case 't':
TOGGLE(screen_context->show_text); TOGGLE(screen_context->show_text);
break; break;
case 'c': case 'c':
TOGGLE(screen_context->show_coxeter_orbit); TOGGLE(screen_context->show_coxeter_orbit);
break; break;
case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '0':
screen_context->mode = key - '0'; screen_context->mode = key - '0';
break; break;
}
return STATUS_REDRAW;
} }
return STATUS_NOTHING; return STATUS_REDRAW;
}
return STATUS_NOTHING;
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
GraphicsInfo *info; GraphicsInfo *info;
screen_context = malloc(sizeof(DrawingContext)); screen_context = malloc(sizeof(DrawingContext));
setupContext(screen_context, argc, argv); setupContext(screen_context, argc, argv);
updateMatrices(screen_context); updateMatrices(screen_context);
computeLimitCurve(screen_context); computeLimitCurve(screen_context);
info = initCairo(0, KeyPressMask, 200, 200, "Triangle group"); info = initCairo(0, KeyPressMask, 200, 200, "Triangle group");
if(!info) if(!info)
return 1; return 1;
/* /*
info->dim->matrix.xx = 274.573171; info->dim->matrix.xx = 274.573171;
info->dim->matrix.xy = 0.000000; info->dim->matrix.xy = 0.000000;
info->dim->matrix.x0 = 583.073462; info->dim->matrix.x0 = 583.073462;
info->dim->matrix.yx = 0.000000; info->dim->matrix.yx = 0.000000;
info->dim->matrix.yy = 274.573171; info->dim->matrix.yy = 274.573171;
info->dim->matrix.y0 = 777.225293; info->dim->matrix.y0 = 777.225293;
*/ */
info->dim->matrix.xx = 274.573171; info->dim->matrix.xx = 274.573171;
info->dim->matrix.xy = 0.000000; info->dim->matrix.xy = 0.000000;
info->dim->matrix.x0 = 910.073462; info->dim->matrix.x0 = 910.073462;
info->dim->matrix.yx = 0.000000; info->dim->matrix.yx = 0.000000;
info->dim->matrix.yy = 274.573171; info->dim->matrix.yy = 274.573171;
info->dim->matrix.y0 = 509.225293; info->dim->matrix.y0 = 509.225293;
updateDimensions(info->dim); updateDimensions(info->dim);
screen_context->dim = info->dim; screen_context->dim = info->dim;
screen_context->cairo = info->buffer_context; screen_context->cairo = info->buffer_context;
startTimer(info); startTimer(info);
while(1) { while(1) {
int result = checkEvents(info, processEvent, NULL); int result = checkEvents(info, processEvent, NULL);
if(result == STATUS_QUIT) if(result == STATUS_QUIT)
return 0; return 0;
else if(result == STATUS_REDRAW) { else if(result == STATUS_REDRAW) {
struct timeval current_time; struct timeval current_time;
double start_time, intermediate_time, end_time; double start_time, intermediate_time, end_time;
gettimeofday(&current_time, 0); gettimeofday(&current_time, 0);
start_time = current_time.tv_sec + current_time.tv_usec*1e-6; start_time = current_time.tv_sec + current_time.tv_usec*1e-6;
draw(screen_context); draw(screen_context);
gettimeofday(&current_time, 0); gettimeofday(&current_time, 0);
intermediate_time = current_time.tv_sec + current_time.tv_usec*1e-6; intermediate_time = current_time.tv_sec + current_time.tv_usec*1e-6;
cairo_set_source_surface(info->front_context, info->buffer_surface, 0, 0); cairo_set_source_surface(info->front_context, info->buffer_surface, 0, 0);
cairo_paint(info->front_context); cairo_paint(info->front_context);
gettimeofday(&current_time, 0); gettimeofday(&current_time, 0);
end_time = current_time.tv_sec + current_time.tv_usec*1e-6; end_time = current_time.tv_sec + current_time.tv_usec*1e-6;
printf("drawing finished in %.2f milliseconds, of which %.2f milliseconds were buffer switching\n", (end_time - start_time) * 1000, (end_time - intermediate_time) * 1000); printf("drawing finished in %.2f milliseconds, of which %.2f milliseconds were buffer switching\n", (end_time - start_time) * 1000, (end_time - intermediate_time) * 1000);
}
waitUpdateTimer(info);
} }
waitUpdateTimer(info);
}
free(screen_context); free(screen_context);
destroyCairo(info); destroyCairo(info);
destroyContext(screen_context); destroyContext(screen_context);
return 0; return 0;
} }

4
main.h
View File

@ -36,6 +36,10 @@ typedef struct {
int p[3],k[3]; int p[3],k[3];
double parameter; double parameter;
double parameter2; double parameter2;
char *movie_filename;
double movie_parameter_duration;
double movie_parameter2_duration;
int movie_n_frames;
int n_group_elements; int n_group_elements;
int n_group_elements_combinatorial; int n_group_elements_combinatorial;
int show_boxes; int show_boxes;