Compare commits

..

No commits in common. "78769593a755c4b82b69c41bf7749b7bbb560f60" and "35932782e9545a419ff57e7632964de0ec59f884" have entirely different histories.

5 changed files with 568 additions and 678 deletions

380
draw.c
View File

@ -46,22 +46,21 @@ int fixedPoints(DrawingContext *ctx, const char *word, vector_t *out)
{ {
gsl_matrix *tmp = getTempMatrix(ctx->ws); gsl_matrix *tmp = getTempMatrix(ctx->ws);
gsl_matrix *ev = getTempMatrix(ctx->ws); gsl_matrix *ev = getTempMatrix(ctx->ws);
gsl_matrix **gen = getTempMatrices(ctx->ws, 6); gsl_matrix **gen = getTempMatrices(ctx->ws, 3);
initializeTriangleGeneratorsCurrent(gen, ctx); initializeTriangleGenerators(gen, ctx->cartan);
gsl_matrix_set_identity(tmp); gsl_matrix_set_identity(tmp);
for(int i = 0; i < strlen(word); i++) { for(int i = 0; i < strlen(word); i++) {
if(word[i] >= 'a' && word[i] <= 'c') if(word[i] == ' ')
continue;
multiply_right(tmp, gen[word[i]-'a'], ctx->ws); multiply_right(tmp, gen[word[i]-'a'], ctx->ws);
else if(word[i] >= 'A' && word[i] <= 'C')
multiply_right(tmp, gen[word[i]-'A'+3], ctx->ws);
} }
int count = real_eigenvectors(tmp, ev, ctx->ws); int count = real_eigenvectors(tmp, ev, ctx->ws);
LOOP(i) LOOP(j) out[i].x[j] = gsl_matrix_get(ev, j, i); LOOP(i) LOOP(j) out[i].x[j] = gsl_matrix_get(ev, j, i);
releaseTempMatrices(ctx->ws, 8); releaseTempMatrices(ctx->ws, 5);
return count; return count;
} }
@ -70,9 +69,9 @@ int wordEigenvalues(DrawingContext *ctx, const char *word, double *out)
{ {
gsl_matrix *tmp = getTempMatrix(ctx->ws); gsl_matrix *tmp = getTempMatrix(ctx->ws);
gsl_vector *ev = getTempVector(ctx->ws); gsl_vector *ev = getTempVector(ctx->ws);
gsl_matrix **gen = getTempMatrices(ctx->ws, 6); gsl_matrix **gen = getTempMatrices(ctx->ws, 3);
initializeTriangleGeneratorsCurrent(gen, ctx); initializeTriangleGenerators(gen, ctx->cartan);
gsl_matrix_set_identity(tmp); gsl_matrix_set_identity(tmp);
for(int i = 0; i < strlen(word); i++) { for(int i = 0; i < strlen(word); i++) {
@ -84,7 +83,7 @@ int wordEigenvalues(DrawingContext *ctx, const char *word, double *out)
LOOP(i) out[i] = gsl_vector_get(ev, i); LOOP(i) out[i] = gsl_vector_get(ev, i);
releaseTempMatrices(ctx->ws, 7); releaseTempMatrices(ctx->ws, 4);
releaseTempVectors(ctx->ws, 1); releaseTempVectors(ctx->ws, 1);
return count; return count;
@ -299,6 +298,8 @@ void drawBoxLines(DrawingContext *ctx, const char *word1, const char *word2)
drawPolygon(ctx, 0, 4, p[0][0], i[0], p[1][0], i[1]); drawPolygon(ctx, 0, 4, p[0][0], i[0], p[1][0], i[1]);
} }
void drawBoxStd(DrawingContext *ctx, const char *word, char base) void drawBoxStd(DrawingContext *ctx, const char *word, char base)
{ {
char word1[100]; char word1[100];
@ -328,13 +329,13 @@ void drawRotationOrbitFrame(DrawingContext *ctx, gsl_matrix *frame, vector_t sta
vector_t v[3], w; vector_t v[3], w;
point_t p; point_t p;
double parameter, startangle; double parameter, startangle;
int iterations = 2000; int iterations = 200;
gsl_matrix *inverse = getTempMatrix(ctx->ws); gsl_matrix *inverse = getTempMatrix(ctx->ws);
gsl_vector *start_v = getTempVector(ctx->ws); gsl_vector *start_v = getTempVector(ctx->ws);
gsl_vector *start_in_frame = getTempVector(ctx->ws); gsl_vector *start_in_frame = getTempVector(ctx->ws);
cairo_t *C = ctx->cairo; cairo_t *C = ctx->cairo;
// computeRotationMatrixFrame(ctx, frame, word); // computeRotationMatrix(ctx, frame, word);
LOOP(i) LOOP(j) v[i].x[j] = gsl_matrix_get(frame, j, i); LOOP(i) LOOP(j) v[i].x[j] = gsl_matrix_get(frame, j, i);
LOOP(i) gsl_vector_set(start_v, i, start.x[i]); LOOP(i) gsl_vector_set(start_v, i, start.x[i]);
@ -370,7 +371,7 @@ void drawRotationOrbit(DrawingContext *ctx, const char *word, vector_t start)
{ {
gsl_matrix *frame = getTempMatrix(ctx->ws); gsl_matrix *frame = getTempMatrix(ctx->ws);
computeRotationMatrixFrame(ctx, frame, word); computeRotationMatrix(ctx, frame, word);
drawRotationOrbitFrame(ctx, frame, start); drawRotationOrbitFrame(ctx, frame, start);
releaseTempMatrices(ctx->ws, 1); releaseTempMatrices(ctx->ws, 1);
@ -388,7 +389,7 @@ void drawDualRotationOrbit(DrawingContext *ctx, const char *word, vector_t start
gsl_vector *start_in_frame = getTempVector(ctx->ws); gsl_vector *start_in_frame = getTempVector(ctx->ws);
cairo_t *C = ctx->cairo; cairo_t *C = ctx->cairo;
computeRotationMatrixFrame(ctx, frame, word); computeRotationMatrix(ctx, frame, word);
LOOP(i) LOOP(j) v[i].x[j] = gsl_matrix_get(frame, j, i); LOOP(i) LOOP(j) v[i].x[j] = gsl_matrix_get(frame, j, i);
LOOP(i) gsl_vector_set(start_v, i, start.x[i]); LOOP(i) gsl_vector_set(start_v, i, start.x[i]);
@ -433,7 +434,7 @@ void drawArcWithOutput(DrawingContext *ctx, const char *word, vector_t start, ve
gsl_vector *vector_in_frame = getTempVector(ctx->ws); gsl_vector *vector_in_frame = getTempVector(ctx->ws);
cairo_t *C = ctx->cairo; cairo_t *C = ctx->cairo;
computeRotationMatrixFrame(ctx, frame, word); computeRotationMatrix(ctx, frame, word);
LOOP(i) LOOP(j) v[i].x[j] = gsl_matrix_get(frame, j, i); LOOP(i) LOOP(j) v[i].x[j] = gsl_matrix_get(frame, j, i);
LOOP(i) gsl_vector_set(vector, i, start.x[i]); LOOP(i) gsl_vector_set(vector, i, start.x[i]);
@ -575,9 +576,9 @@ void drawAttractors(DrawingContext *ctx)
vector_t p[6][3]; vector_t p[6][3];
vector_t l[6][3]; vector_t l[6][3];
fixedPoints(ctx, "cba", p[0]); fixedPoints(ctx, "abc", p[0]);
fixedPoints(ctx, "bac", p[1]); fixedPoints(ctx, "bca", p[1]);
fixedPoints(ctx, "acb", p[2]); fixedPoints(ctx, "cab", p[2]);
fixedPoints(ctx, "a cab a", p[3]); fixedPoints(ctx, "a cab a", p[3]);
fixedPoints(ctx, "b abc b", p[4]); fixedPoints(ctx, "b abc b", p[4]);
fixedPoints(ctx, "c bca c", p[5]); fixedPoints(ctx, "c bca c", p[5]);
@ -704,180 +705,200 @@ void drawCurvedBox(DrawingContext *ctx, int base, const char *conj, int style)
} }
} }
groupelement_t *left(const char *word, groupelement_t *g)
{
int n = strlen(word);
for(int i = n-1; i >= 0; i--) {
if(word[i] == ' ')
continue;
g = g->adj[word[i]-'a'];
if(!g)
break;
}
return g;
}
void drawBoxes(DrawingContext *ctx) void drawBoxes(DrawingContext *ctx)
{ {
gsl_matrix *tmp = getTempMatrix(ctx->ws); gsl_matrix *rot = getTempMatrix(ctx->ws);
gsl_matrix **gen = getTempMatrices(ctx->ws, 6); gsl_matrix **gen = getTempMatrices(ctx->ws, 3);
gsl_matrix *frame = getTempMatrix(ctx->ws); gsl_matrix *frame = getTempMatrix(ctx->ws);
gsl_matrix *frame2 = getTempMatrix(ctx->ws);
gsl_vector *startpoint_drawbasis = getTempVector(ctx->ws);
gsl_vector *startpoint_globalbasis = getTempVector(ctx->ws);
gsl_matrix **elements = getTempMatrices(ctx->ws, ctx->n_group_elements);
cairo_t *C = ctx->cairo; cairo_t *C = ctx->cairo;
cairo_save(C); cairo_save(C);
cairo_set_line_width(C, 2.0/ctx->dim->scalefactor);
cairo_set_source_rgb(C, 0.6, 0.6, 0.6);
vector_t p[22][3]; vector_t p[22][3];
vector_t fp[3];
vector_t l[22][3]; vector_t l[22][3];
vector_t alpha[6]; vector_t alpha[6];
vector_t ptmp[3]; vector_t ptmp[3];
vector_t start;
vector_t start2;
char word[100], word2[100]; char word[100], word2[100];
fixedPoints(ctx, "cba", p[0]); fixedPoints(ctx, "abc", p[0]);
fixedPoints(ctx, "acb", p[1]); fixedPoints(ctx, "bca", p[1]);
fixedPoints(ctx, "bac", p[2]); fixedPoints(ctx, "cab", p[2]);
fixedPoints(ctx, "bacabab", p[3]);
fixedPoints(ctx, "bcacabacb", p[4]);
initializeTriangleGeneratorsCurrent(gen, ctx); cairo_set_line_width(C, 2.0/ctx->dim->scalefactor);
gsl_matrix_set_identity(elements[0]); cairo_set_source_rgb(C, 0.6, 0.6, 0.6);
for(int i = 1; i < ctx->n_group_elements; i++) {
if(ctx->group[i].length % 2) drawRotationOrbit(ctx, "ab", p[0][0]);
continue; drawRotationOrbit(ctx, "bc", p[0][0]);
int letter = ROTATION_LETTER(ctx->group[i].letter, ctx->group[i].parent->letter); drawRotationOrbit(ctx, "ca", p[0][0]);
multiply(gen[letter], elements[ctx->group[i].parent->parent->id], elements[i]);
if(ctx->mode >= 2) {
cairo_set_source_rgb(C, 0.6, 0.6, 1);
drawRotationOrbit(ctx, "bcabcb", p[1][0]); // bcC
drawRotationOrbit(ctx, "abcabcba", p[0][0]); // abcC
// drawRotationOrbit(ctx, "bcabcabacb", p[1][0]); // bcabC''
// drawRotationOrbit(ctx, "bacabcacab", p[3][0]); // bacaC'
// drawRotationOrbit(ctx, "bcacabcacacb", p[4][0]); // bcacaC' bcacabacb
} }
gsl_vector_set(startpoint_drawbasis, 0, ctx->marking.x); cairo_set_source_rgb(C, 1, 0, 1);
gsl_vector_set(startpoint_drawbasis, 1, ctx->marking.y); // drawRotationOrbit(ctx, "bacabcacab", p[3][0]); // ababcba
gsl_vector_set(startpoint_drawbasis, 2, 1); cairo_set_source_rgb(C, 0, 0, 0);
solve(ctx->cob, startpoint_drawbasis, startpoint_globalbasis, ctx->ws); fixedPoints(ctx, "abababcbaba", p[3]);
LOOP(i) start.x[i] = gsl_vector_get(startpoint_globalbasis, i); // drawRotationOrbit(ctx, "abababcabcbababa", p[3][0]); // bab abc bab
cairo_set_source_rgb(C, 0, 0, 1);
// fixedPoints(ctx, "cab", p[3]);
// drawRotationOrbit(ctx, "cabc", p[3][0]);
// fixedPoints(ctx, "bca", p[3]);
// drawRotationOrbit(ctx, "bcabcb", p[3][0]);
// fixedPoints(ctx, "bc abc cb", p[3]);
// drawRotationOrbit(ctx, "bcabcb", p[3][0]);
fixedPoints(ctx, "bc bca cb", p[3]);
// drawRotationOrbit(ctx, "bcbcacbc", p[3][0]);
/* /*
fixedPoints(ctx, "ABAB", fp); cairo_set_source_rgb(C, 0, 0, 0);
drawCovector(ctx, cross(fp[0], fp[2])); strncpy(word,"abc",100);
drawVector(ctx, fp[1]); for(int i = 0; i < 9; i++) {
computeRotationMatrixFrame(ctx, frame, "c"); conjugate_word(word, 0, "ab", word2);
drawRotationOrbit(ctx, "c", start); // ba cb ab ac = C A c B strncpy(word, word2, 100);
drawVector(ctx, start); fixedPoints(ctx, word, ptmp);
drawVector(ctx, ptmp[0]);
computeMatrix(ctx, tmp, "ABABc"); // drawVector(ctx, ptmp[2]);
start2 = apply(tmp, start);
computeRotationMatrixFrame(ctx, frame, "c");
multiply(tmp, frame, frame2);
drawVector(ctx, start2);
drawRotationOrbitFrame(ctx, frame2, apply(tmp, start));
computeMatrix(ctx, tmp, "ABABcABABC");
start2 = apply(tmp, start);
computeRotationMatrixFrame(ctx, frame, "c");
multiply(tmp, frame, frame2);
drawVector(ctx, start2);
drawRotationOrbitFrame(ctx, frame2, apply(tmp, start));
*/
for(groupelement_t *cur = &ctx->group[180]; cur->parent; cur = cur->parent)
fputc('a'+cur->letter, stdout);
fputc('\n', stdout);
queue_t queue;
queue_init(&queue);
queue_put(&queue, 0);
int current;
groupelement_t *cur, *next;
for(int i = 0; i < ctx->n_group_elements_combinatorial; i++)
ctx->group[i].visited = 0;
cur = &ctx->group[0];
computeRotationMatrixFrame(ctx, frame, "c");
for(int i = 0; i < 1000; i++) {
if(ctx->group[i].length % 2 != 0)
continue;
multiply(elements[i], frame, frame2);
drawRotationOrbitFrame(ctx, frame2, apply(elements[i], start));
} }
/* strncpy(word,"bca",100);
while((current = queue_get(&queue)) != -1) { for(int i = 0; i < 9; i++) {
cur = &ctx->group[current]; conjugate_word(word, 0, "ab", word2);
strncpy(word, word2, 100);
if(cur->visited > 4) fixedPoints(ctx, word, ptmp);
continue; drawVector(ctx, ptmp[0]);
// drawVector(ctx, ptmp[2]);
if(cur->id < ctx->n_group_elements) {
multiply(elements[cur->id], frame, frame2);
drawRotationOrbitFrame(ctx, frame2, apply(elements[cur->id], start));
} }
next = left("ab ab", cur);
if(next && next->visited == 0) { strncpy(word,"abc",100);
queue_put(&queue, next->id); for(int i = 0; i < 9; i++) {
next->visited = cur->visited+1; conjugate_word(word, 0, "bc", word2);
strncpy(word, word2, 100);
fixedPoints(ctx, word, ptmp);
drawVector(ctx, ptmp[0]);
} }
next = left("cbac cbac", cur);
if(next && next->visited == 0) { strncpy(word,"cab",100);
queue_put(&queue, next->id); for(int i = 0; i < 9; i++) {
next->visited = cur->visited+1; conjugate_word(word, 0, "bc", word2);
strncpy(word, word2, 100);
fixedPoints(ctx, word, ptmp);
drawVector(ctx, ptmp[0]);
} }
next = left("cacbca cacbca", cur);
if(next && next->visited == 0) { strncpy(word,"cab",100);
queue_put(&queue, next->id); for(int i = 0; i < 9; i++) {
next->visited = cur->visited+1; conjugate_word(word, 0, "ca", word2);
} strncpy(word, word2, 100);
next = left("cabcacbcac cabcacbcac", cur); fixedPoints(ctx, word, ptmp);
if(next && next->visited == 0) { drawVector(ctx, ptmp[0]);
queue_put(&queue, next->id);
next->visited = cur->visited+1;
}
next = left("acbcacba acbcacba", cur);
if(next && next->visited == 0) {
queue_put(&queue, next->id);
next->visited = cur->visited+1;
}
next = left("bcacbc bcacbc", cur);
if(next && next->visited == 0) {
queue_put(&queue, next->id);
next->visited = cur->visited+1;
} }
strncpy(word,"abc",100);
for(int i = 0; i < 9; i++) {
conjugate_word(word, 0, "ca", word2);
strncpy(word, word2, 100);
fixedPoints(ctx, word, ptmp);
drawVector(ctx, ptmp[0]);
} }
*/ */
// drawRotationOrbit(ctx, "a", p[1][0]); /*
// drawRotationOrbit(ctx, "b", p[2][0]); cairo_set_source_rgb(C, 1, 0, 0);
drawVector(ctx, p[0][0]);
cairo_set_source_rgb(C, 0, 0.6, 0);
drawVector(ctx, p[1][0]);
cairo_set_source_rgb(C, 0, 0, 1);
drawVector(ctx, p[2][0]);
*/
/*
fixedPoints(ctx, "ab abc ba", p[4]);
fixedPoints(ctx, "abab abc baba", p[5]);
fixedPoints(ctx, "ababab abc bababa", p[6]);
fixedPoints(ctx, "abababab abc babababa", p[7]);
fixedPoints(ctx, "babababa abc abababab", p[8]);
fixedPoints(ctx, "bababa abc ababab", p[9]);
fixedPoints(ctx, "baba abc abab", p[10]);
fixedPoints(ctx, "ba abc ab", p[11]);
fixedPoints(ctx, "bca", p[12]);
fixedPoints(ctx, "b abc b", p[13]);
fixedPoints(ctx, "bab abc bab", p[14]);
fixedPoints(ctx, "babab abc babab", p[15]);
fixedPoints(ctx, "bababab abc bababab", p[16]);
fixedPoints(ctx, "abababab bca babababa", p[17]);
fixedPoints(ctx, "ababab bca bababa", p[18]);
fixedPoints(ctx, "abab bca baba", p[19]);
fixedPoints(ctx, "ab bca ba", p[20]);
*/
// initializeTriangleGenerators(gen, ctx->cartan);
// for(int i = 0; i < 22; i++) LOOP(j) l[i][j] = cross(p[i][(3-j)%3], p[i][(4-j)%3]);
// LOOP(i) LOOP(j) alpha[i].x[j] = gsl_matrix_get(ctx->cartan, i, j);
/*
gsl_matrix_set(frame, 0, 0, 2.0);
gsl_matrix_set(frame, 0, 1, 0.0);
gsl_matrix_set(frame, 0, 2, 1.0);
gsl_matrix_set(frame, 1, 0, -1.0);
gsl_matrix_set(frame, 1, 1, sqrt(3));
gsl_matrix_set(frame, 1, 2, 1.0);
gsl_matrix_set(frame, 2, 0, -1.0);
gsl_matrix_set(frame, 2, 1, -sqrt(3));
gsl_matrix_set(frame, 2, 2, 1.0);*/
// drawRotationOrbitFrame(ctx, frame, p[0][0]);
// drawRotationOrbit(ctx, "bc", p[0][0]);
// drawRotationOrbit(ctx, "ca", p[0][0]);
/*
for(int i = 0; i < 18; i++) {
if(i == 0)
cairo_set_source_rgb(C, 1, 0, 0);
else if(i == 8)
cairo_set_source_rgb(C, 0, 0, 1);
else if(i == 9)
cairo_set_source_rgb(C, 0, 0.6, 0);
else
cairo_set_source_rgb(C, 0, 0, 0);
drawVector(ctx, p[3+i][0]);
// drawCovector(ctx, l[3+i][0]);
}
*/
// drawRotationOrbit(ctx, "ab", cross(l[0][0], l[2][1]));
// drawRotationOrbit(ctx, "abca", p[0][0]);
cairo_restore(C); cairo_restore(C);
releaseTempMatrices(ctx->ws, 9 + ctx->n_group_elements); releaseTempMatrices(ctx->ws, 5);
releaseTempVectors(ctx->ws, 2);
} }
void drawBoxes2(DrawingContext *ctx) void drawBoxes2(DrawingContext *ctx)
{ {
gsl_matrix *rot = getTempMatrix(ctx->ws); gsl_matrix *rot = getTempMatrix(ctx->ws);
gsl_matrix **gen = getTempMatrices(ctx->ws, 6); gsl_matrix **gen = getTempMatrices(ctx->ws, 3);
cairo_t *C = ctx->cairo; cairo_t *C = ctx->cairo;
cairo_save(C); cairo_save(C);
initializeTriangleGeneratorsCurrent(gen, ctx); initializeTriangleGenerators(gen, ctx->cartan);
vector_t p[4][3]; vector_t p[4][3];
fixedPoints(ctx, "cba", p[0]); fixedPoints(ctx, "abc", p[0]);
fixedPoints(ctx, "acb", p[1]); fixedPoints(ctx, "bca", p[1]);
fixedPoints(ctx, "bac", p[2]); fixedPoints(ctx, "cab", p[2]);
cairo_set_line_width(C, 2.5/ctx->dim->scalefactor); cairo_set_line_width(C, 2.5/ctx->dim->scalefactor);
@ -1241,13 +1262,13 @@ void drawBoxes2(DrawingContext *ctx)
*/ */
cairo_restore(C); cairo_restore(C);
releaseTempMatrices(ctx->ws, 7); releaseTempMatrices(ctx->ws, 4);
} }
void drawRotatedReflectors(DrawingContext *ctx) void drawRotatedReflectors(DrawingContext *ctx)
{ {
gsl_matrix *rot = getTempMatrix(ctx->ws); gsl_matrix *rot = getTempMatrix(ctx->ws);
gsl_matrix **gen = getTempMatrices(ctx->ws, 6); gsl_matrix **gen = getTempMatrices(ctx->ws, 3);
cairo_t *C = ctx->cairo; cairo_t *C = ctx->cairo;
vector_t fp[3], fp2[3]; vector_t fp[3], fp2[3];
vector_t w; vector_t w;
@ -1255,7 +1276,7 @@ void drawRotatedReflectors(DrawingContext *ctx)
cairo_set_source_rgb(C, 0.7, 0.7, 0.7); cairo_set_source_rgb(C, 0.7, 0.7, 0.7);
initializeTriangleGeneratorsCurrent(gen, ctx); initializeTriangleGenerators(gen, ctx->cartan);
LOOP(i) LOOP(j) v[i].x[j] = gsl_matrix_get(ctx->cartan, i, j); LOOP(i) LOOP(j) v[i].x[j] = gsl_matrix_get(ctx->cartan, i, j);
multiply(gen[0], gen[1], rot); multiply(gen[0], gen[1], rot);
@ -1276,7 +1297,7 @@ void drawRotatedReflectors(DrawingContext *ctx)
fixedPoints(ctx, "cacabac", fp2); fixedPoints(ctx, "cacabac", fp2);
drawRotationOrbit(ctx, "ac", fp[0]); drawRotationOrbit(ctx, "ac", fp[0]);
releaseTempMatrices(ctx->ws, 7); releaseTempMatrices(ctx->ws, 4);
} }
void drawDualLimitCurve(DrawingContext *ctx) void drawDualLimitCurve(DrawingContext *ctx)
@ -1286,36 +1307,12 @@ void drawDualLimitCurve(DrawingContext *ctx)
cairo_save(C); cairo_save(C);
cairo_set_source_rgb(C, 0.5, 0.5, 1); cairo_set_source_rgb(C, 0.5, 0.5, 1);
gsl_matrix **gen = getTempMatrices(ctx->ws, 6); int n = 18;
gsl_matrix **elements = getTempMatrices(ctx->ws, ctx->n_group_elements); vector_t p[n][3];
vector_t l[n][3];
vector_t ptmp[3], ltmp[3];
// wordEigenvalues(ctx, "abc", ev); fixedPoints(ctx, "abc", p[0]);
// LOOP(i) LOOP(j) gsl_matrix_set(coxeter_fixedpoints, j, i, cox[0][i].x[j]);
initializeTriangleGeneratorsCurrent(gen, ctx);
gsl_matrix_set_identity(elements[0]);
for(int i = 1; i < ctx->n_group_elements; i++)
multiply(gen[ctx->group[i].letter], elements[ctx->group[i].parent->id], elements[i]);
vector_t p[3], l[3], v;
fixedPoints(ctx, "cba", p);
drawVector(ctx, p[0]);
drawVector(ctx, p[1]);
drawVector(ctx, p[2]);
LOOP(i) l[i] = cross(p[(i+1)%3], p[(i+2)%3]);
for(int i = 0; i < ctx->n_group_elements; i++) {
v = apply_transpose(elements[i], l[0]);
drawCovector(ctx, v);
}
releaseTempMatrices(ctx->ws, 3 + ctx->n_group_elements);
// releaseTempVectors(ctx->ws, 4);
/*
fixedPoints(ctx, "ab abc ba", p[1]); fixedPoints(ctx, "ab abc ba", p[1]);
fixedPoints(ctx, "abab abc baba", p[2]); fixedPoints(ctx, "abab abc baba", p[2]);
fixedPoints(ctx, "ababab abc bababa", p[3]); fixedPoints(ctx, "ababab abc bababa", p[3]);
@ -1334,7 +1331,6 @@ void drawDualLimitCurve(DrawingContext *ctx)
fixedPoints(ctx, "bababa bca ababab", p[15]); fixedPoints(ctx, "bababa bca ababab", p[15]);
fixedPoints(ctx, "baba bca abab", p[16]); fixedPoints(ctx, "baba bca abab", p[16]);
fixedPoints(ctx, "ba bca ab", p[17]); fixedPoints(ctx, "ba bca ab", p[17]);
*/
/* /*
fixedPoints(ctx, "abc", p[0]); fixedPoints(ctx, "abc", p[0]);
@ -1372,7 +1368,6 @@ void drawDualLimitCurve(DrawingContext *ctx)
// drawCovector(ctx, l[i][2]); // drawCovector(ctx, l[i][2]);
}*/ }*/
/*
fixedPoints(ctx, "abc", ptmp); fixedPoints(ctx, "abc", ptmp);
drawCovector(ctx, cross(ptmp[0], ptmp[1])); drawCovector(ctx, cross(ptmp[0], ptmp[1]));
fixedPoints(ctx, "bca", ptmp); fixedPoints(ctx, "bca", ptmp);
@ -1385,7 +1380,6 @@ void drawDualLimitCurve(DrawingContext *ctx)
drawCovector(ctx, cross(ptmp[0], ptmp[1])); drawCovector(ctx, cross(ptmp[0], ptmp[1]));
fixedPoints(ctx, "acaba", ptmp); fixedPoints(ctx, "acaba", ptmp);
drawCovector(ctx, cross(ptmp[0], ptmp[1])); drawCovector(ctx, cross(ptmp[0], ptmp[1]));
*/
cairo_restore(C); cairo_restore(C);
} }
@ -1441,7 +1435,7 @@ void drawLimitCurve(DrawingContext *ctx)
void drawCoxeterOrbit(DrawingContext *ctx) void drawCoxeterOrbit(DrawingContext *ctx)
{ {
gsl_matrix *rot = getTempMatrix(ctx->ws); gsl_matrix *rot = getTempMatrix(ctx->ws);
gsl_matrix **gen = getTempMatrices(ctx->ws, 6); gsl_matrix **gen = getTempMatrices(ctx->ws, 3);
gsl_vector *eval = getTempVector(ctx->ws); gsl_vector *eval = getTempVector(ctx->ws);
gsl_matrix *coxeter_fixedpoints = getTempMatrix(ctx->ws); gsl_matrix *coxeter_fixedpoints = getTempMatrix(ctx->ws);
gsl_vector *startpoint_coxeterbasis = getTempVector(ctx->ws); gsl_vector *startpoint_coxeterbasis = getTempVector(ctx->ws);
@ -1458,7 +1452,7 @@ void drawCoxeterOrbit(DrawingContext *ctx)
int first = 1; int first = 1;
cairo_save(C); cairo_save(C);
initializeTriangleGeneratorsCurrent(gen, ctx); initializeTriangleGenerators(gen, ctx->cartan);
cairo_set_source_rgb(C, 0, 0, 1); cairo_set_source_rgb(C, 0, 0, 1);
@ -1469,7 +1463,7 @@ void drawCoxeterOrbit(DrawingContext *ctx)
wordEigenvalues(ctx, "abc", ev); wordEigenvalues(ctx, "abc", ev);
LOOP(i) LOOP(j) gsl_matrix_set(coxeter_fixedpoints, j, i, cox[0][i].x[j]); LOOP(i) LOOP(j) gsl_matrix_set(coxeter_fixedpoints, j, i, cox[0][i].x[j]);
initializeTriangleGeneratorsCurrent(gen, ctx); initializeTriangleGenerators(gen, ctx->cartan);
gsl_matrix_set_identity(elements[0]); gsl_matrix_set_identity(elements[0]);
for(int i = 1; i < ctx->n_group_elements; i++) for(int i = 1; i < ctx->n_group_elements; i++)
multiply(gen[ctx->group[i].letter], elements[ctx->group[i].parent->id], elements[i]); multiply(gen[ctx->group[i].letter], elements[ctx->group[i].parent->id], elements[i]);
@ -1483,7 +1477,7 @@ void drawCoxeterOrbit(DrawingContext *ctx)
gsl_vector_set(startpoint_drawbasis, 2, 1); gsl_vector_set(startpoint_drawbasis, 2, 1);
solve(ctx->cob, startpoint_drawbasis, startpoint_globalbasis, ctx->ws); solve(ctx->cob, startpoint_drawbasis, startpoint_globalbasis, ctx->ws);
// solve(coxeter_fixedpoints, startpoint_globalbasis, startpoint_coxeterbasis, ctx->ws); solve(coxeter_fixedpoints, startpoint_globalbasis, startpoint_coxeterbasis, ctx->ws);
// LOOP(i) start.x[i] = gsl_vector_get(startpoint_coxeterbasis, i); // LOOP(i) start.x[i] = gsl_vector_get(startpoint_coxeterbasis, i);
LOOP(i) start.x[i] = gsl_vector_get(startpoint_globalbasis, i); LOOP(i) start.x[i] = gsl_vector_get(startpoint_globalbasis, i);
@ -1523,7 +1517,7 @@ void drawCoxeterOrbit(DrawingContext *ctx)
// LOOP(i) drawVector(ctx, abcb[i]); // LOOP(i) drawVector(ctx, abcb[i]);
cairo_restore(C); cairo_restore(C);
releaseTempMatrices(ctx->ws, 8 + ctx->n_group_elements); releaseTempMatrices(ctx->ws, 5 + ctx->n_group_elements);
releaseTempVectors(ctx->ws, 4); releaseTempVectors(ctx->ws, 4);
} }
@ -1532,7 +1526,7 @@ void drawText(DrawingContext *ctx)
cairo_move_to(ctx->cairo, 15, 30); cairo_move_to(ctx->cairo, 15, 30);
cairo_set_source_rgb(ctx->cairo, 0, 0, 0); cairo_set_source_rgb(ctx->cairo, 0, 0, 0);
char buf[100]; char buf[100];
sprintf(buf, "t = exp(%.8f) = %.8f, s = exp(%.8f) = %.8f, marking = (%.5f, %.5f)", log(ctx->parameter), ctx->parameter, log(ctx->parameter2), ctx->parameter2, ctx->marking.x, ctx->marking.y); sprintf(buf, "t = exp(%.8f) = %.8f, marking = (%.5f, %.5f)", log(ctx->parameter), ctx->parameter, ctx->marking.x, ctx->marking.y);
cairo_show_text(ctx->cairo, buf); cairo_show_text(ctx->cairo, buf);
} }

View File

@ -5,7 +5,6 @@ static int compareAngle(const void *x, const void *y)
return ((double*)x)[2] > ((double*)y)[2] ? 1 : -1; return ((double*)x)[2] > ((double*)y)[2] ? 1 : -1;
} }
// might need a rewrite
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);
@ -21,58 +20,11 @@ void cartanMatrix(gsl_matrix *cartan, double a1, double a2, double a3, double s)
gsl_matrix_set(cartan, 2, 2, 2); gsl_matrix_set(cartan, 2, 2, 2);
} }
void initializeTriangleGenerators(gsl_matrix **gen, double a1, double a2, double a3, double s, double t, workspace_t *ws) void initializeTriangleGenerators(gsl_matrix **gen, gsl_matrix *cartan)
{ {
gsl_matrix *reflection_gen[3]; LOOP(i) gsl_matrix_set_identity(gen[i]);
LOOP(i) LOOP(j) *gsl_matrix_ptr(gen[i], j, j) = -1.0;
LOOP(i) { LOOP(i) LOOP(j) *gsl_matrix_ptr(gen[i], i, j) += gsl_matrix_get(cartan, i, j);
reflection_gen[i] = gsl_matrix_alloc(3, 3);
gsl_matrix_set_identity(reflection_gen[i]);
}
double rho[3];
rho[0] = sqrt(s*s + 2*s*cos(a1) + 1);
rho[1] = sqrt(s*s + 2*s*cos(a2) + 1);
rho[2] = sqrt(s*s + 2*s*cos(a3) + 1);
gsl_matrix_set(reflection_gen[0], 0, 0, -1.0);
gsl_matrix_set(reflection_gen[0], 0, 1, rho[2]*t);
gsl_matrix_set(reflection_gen[0], 0, 2, rho[1]/t);
gsl_matrix_set(reflection_gen[1], 1, 0, rho[2]/t);
gsl_matrix_set(reflection_gen[1], 1, 1, -1.0);
gsl_matrix_set(reflection_gen[1], 1, 2, rho[0]*t);
gsl_matrix_set(reflection_gen[2], 2, 0, rho[1]*t);
gsl_matrix_set(reflection_gen[2], 2, 1, rho[0]/t);
gsl_matrix_set(reflection_gen[2], 2, 2, -1.0);
LOOP(i) {
gsl_matrix_set_identity(gen[i]);
gsl_matrix_set(gen[i], (i+1)%3, (i+1)%3, s);
gsl_matrix_set(gen[i], (i+2)%3, (i+2)%3, 1/s);
gsl_matrix_set_identity(gen[i+3]);
gsl_matrix_set(gen[i+3], (i+1)%3, (i+1)%3, 1/s);
gsl_matrix_set(gen[i+3], (i+2)%3, (i+2)%3, s);
}
LOOP(i) {
multiply_left(reflection_gen[i], gen[(i+2)%3], ws);
multiply_right(gen[(i+2)%3], reflection_gen[(i+1)%3], ws);
multiply_left(reflection_gen[(i+1)%3], gen[(i+2)%3+3], ws);
multiply_right(gen[(i+2)%3+3], reflection_gen[i], ws);
}
LOOP(i) gsl_matrix_free(reflection_gen[i]);
}
void initializeTriangleGeneratorsCurrent(gsl_matrix **gen, DrawingContext *ctx)
{
double angle[3];
LOOP(i) angle[i] = 2*M_PI*ctx->k[i]/ctx->p[i];
initializeTriangleGenerators(gen, angle[0], angle[1], angle[2], ctx->parameter2, ctx->parameter, ctx->ws);
} }
int computeLimitCurve(DrawingContext *ctx) int computeLimitCurve(DrawingContext *ctx)
@ -86,7 +38,7 @@ int computeLimitCurve(DrawingContext *ctx)
gsl_matrix *coxeter = getTempMatrix(ctx->ws); gsl_matrix *coxeter = getTempMatrix(ctx->ws);
gsl_matrix *coxeter_fixedpoints = getTempMatrix(ctx->ws); gsl_matrix *coxeter_fixedpoints = getTempMatrix(ctx->ws);
gsl_matrix *fixedpoints = getTempMatrix(ctx->ws); gsl_matrix *fixedpoints = getTempMatrix(ctx->ws);
gsl_matrix **gen = getTempMatrices(ctx->ws, 6); gsl_matrix **gen = getTempMatrices(ctx->ws, 3);
gsl_matrix **elements = getTempMatrices(ctx->ws, ctx->n_group_elements); gsl_matrix **elements = getTempMatrices(ctx->ws, ctx->n_group_elements);
groupelement_t *group = ctx->group; groupelement_t *group = ctx->group;
int success = 0; int success = 0;
@ -98,43 +50,31 @@ int computeLimitCurve(DrawingContext *ctx)
// do first in the Fuchsian positive case to get the angles // do first in the Fuchsian positive case to get the angles
cartanMatrix(cartan_pos, M_PI/ctx->p[0], M_PI/ctx->p[1], M_PI/ctx->p[2], 1.0); cartanMatrix(cartan_pos, M_PI/ctx->p[0], M_PI/ctx->p[1], M_PI/ctx->p[2], 1.0);
initializeTriangleGenerators(gen, 2*M_PI/ctx->p[0], 2*M_PI/ctx->p[1], 2*M_PI/ctx->p[2], 1.0, 1.0, ctx->ws); initializeTriangleGenerators(gen, cartan_pos);
gsl_matrix_set_identity(elements[0]); gsl_matrix_set_identity(elements[0]);
for(int i = 1; i < ctx->n_group_elements; i++) { for(int i = 1; i < ctx->n_group_elements; i++)
if(group[i].length % 2) multiply(gen[group[i].letter], elements[group[i].parent->id], elements[i]);
continue;
int letter = ROTATION_LETTER(group[i].letter, group[i].parent->letter);
multiply(gen[letter], elements[group[i].parent->parent->id], elements[i]);
}
diagonalize_symmetric_form(cartan_pos, cob_pos, ws); diagonalize_symmetric_form(cartan_pos, cob_pos, ws);
multiply_many(ws, coxeter_pos, 3, gen[2], gen[1], gen[0]); multiply_many(ws, coxeter_pos, 3, gen[0], gen[1], gen[2]);
int ev_count_pos = real_eigenvectors(coxeter_pos, coxeter_fixedpoints_pos, ws); int ev_count_pos = real_eigenvectors(coxeter_pos, coxeter_fixedpoints_pos, ws);
if(ev_count_pos != 3) if(ev_count_pos != 3)
goto error_out; goto error_out;
int n = 0;
for(int i = 0; i < ctx->n_group_elements; i++) { for(int i = 0; i < ctx->n_group_elements; i++) {
if(group[i].length % 2)
continue;
multiply_many(ws, fixedpoints_pos, 3, cob_pos, elements[i], coxeter_fixedpoints_pos); multiply_many(ws, fixedpoints_pos, 3, cob_pos, elements[i], coxeter_fixedpoints_pos);
ctx->limit_curve[3*n+2] = atan2( ctx->limit_curve[3*i+2] = atan2(
gsl_matrix_get(fixedpoints_pos, 2, column)/gsl_matrix_get(fixedpoints_pos, 0, column), gsl_matrix_get(fixedpoints_pos, 2, column)/gsl_matrix_get(fixedpoints_pos, 0, column),
gsl_matrix_get(fixedpoints_pos, 1, column)/gsl_matrix_get(fixedpoints_pos, 0, column)); gsl_matrix_get(fixedpoints_pos, 1, column)/gsl_matrix_get(fixedpoints_pos, 0, column));
n++;
} }
// now do it again to calculate x and y coordinates // now do it again to calculate x and y coordinates
initializeTriangleGeneratorsCurrent(gen, ctx); initializeTriangleGenerators(gen, ctx->cartan);
gsl_matrix_set_identity(elements[0]); gsl_matrix_set_identity(elements[0]);
for(int i = 1; i < ctx->n_group_elements; i++) { for(int i = 1; i < ctx->n_group_elements; i++)
if(group[i].length % 2) multiply(gen[group[i].letter], elements[group[i].parent->id], elements[i]);
continue;
int letter = ROTATION_LETTER(group[i].letter, group[i].parent->letter);
multiply(gen[letter], elements[group[i].parent->parent->id], elements[i]);
}
multiply_many(ws, coxeter, 3, gen[2], gen[1], gen[0]); multiply_many(ws, coxeter, 3, gen[0], gen[1], gen[2]);
int ev_count = real_eigenvectors(coxeter, coxeter_fixedpoints, ws); int ev_count = real_eigenvectors(coxeter, coxeter_fixedpoints, ws);
if(ev_count == 1) if(ev_count == 1)
@ -142,17 +82,11 @@ int computeLimitCurve(DrawingContext *ctx)
if(ev_count == 0) if(ev_count == 0)
goto error_out; goto error_out;
ctx->limit_curve_count = 0;
for(int i = 0; i < ctx->n_group_elements; i++) { for(int i = 0; i < ctx->n_group_elements; i++) {
if(group[i].length % 2)
continue;
multiply_many(ws, fixedpoints, 3, ctx->cob, elements[i], coxeter_fixedpoints); multiply_many(ws, fixedpoints, 3, ctx->cob, elements[i], coxeter_fixedpoints);
x = ctx->limit_curve[3*ctx->limit_curve_count ] = gsl_matrix_get(fixedpoints, 0, column)/gsl_matrix_get(fixedpoints, 2, column); x = ctx->limit_curve[3*i ] = gsl_matrix_get(fixedpoints, 0, column)/gsl_matrix_get(fixedpoints, 2, column);
y = ctx->limit_curve[3*ctx->limit_curve_count+1] = gsl_matrix_get(fixedpoints, 1, column)/gsl_matrix_get(fixedpoints, 2, column); y = ctx->limit_curve[3*i+1] = gsl_matrix_get(fixedpoints, 1, column)/gsl_matrix_get(fixedpoints, 2, column);
ctx->limit_curve_count++;
if((x - ctx->marking.x)*(x - ctx->marking.x) + (y - ctx->marking.y)*(y - ctx->marking.y) < 25e-10) if((x - ctx->marking.x)*(x - ctx->marking.x) + (y - ctx->marking.y)*(y - ctx->marking.y) < 25e-10)
{ {
@ -161,16 +95,19 @@ int computeLimitCurve(DrawingContext *ctx)
fputc('a' + cur->letter, stdout); // bcbcbca, bacbcacab, bc bca cb fputc('a' + cur->letter, stdout); // bcbcbca, bacbcacab, bc bca cb
fputc('\n',stdout); fputc('\n',stdout);
} }
// bca abc acb = abc
} }
qsort(ctx->limit_curve, ctx->limit_curve_count, 3*sizeof(double), compareAngle); qsort(ctx->limit_curve, ctx->n_group_elements, 3*sizeof(double), compareAngle);
// ctx->limit_curve_count = ctx->n_group_elements; ctx->limit_curve_count = ctx->n_group_elements;
success = 1; success = 1;
error_out: error_out:
releaseTempMatrices(ctx->ws, 14+ctx->n_group_elements); releaseTempMatrices(ctx->ws, 11+ctx->n_group_elements);
return success; return success;
} }

149
main.c
View File

@ -11,7 +11,6 @@
#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;
@ -19,7 +18,6 @@ DrawingContext *screen_context;
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->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]);
@ -30,33 +28,21 @@ void setupContext(DrawingContext *ctx, int argc, char *argv[])
ctx->parameter = atof(argv[7]); ctx->parameter = atof(argv[7]);
else else
ctx->parameter = 1.0; ctx->parameter = 1.0;
if(argc > 8) // ctx->parameter = 2.77;
ctx->parameter2 = atof(argv[8]); // ctx->parameter = 0.1;
else
ctx->parameter2 = 1.0;
if(argc > 12) {
ctx->movie_filename = argv[9];
ctx->movie_parameter_duration = atof(argv[10]);
ctx->movie_parameter2_duration = atof(argv[11]);
ctx->movie_n_frames = atoi(argv[12]);
} else {
ctx->movie_n_frames = 0;
}
// ctx->parameter = 2.77;
// ctx->parameter = 0.1;
ctx->show_boxes = 0; ctx->show_boxes = 0;
ctx->show_boxes2 = 0; ctx->show_boxes2 = 0;
ctx->show_attractors = 0; ctx->show_attractors = 0;
ctx->show_reflectors = 0; ctx->show_reflectors = 0;
ctx->show_rotated_reflectors = 0; ctx->show_rotated_reflectors = 0;
ctx->show_limit = 0; ctx->show_limit= 0;
ctx->show_dual_limit = 0; ctx->show_dual_limit= 0;
ctx->show_text = 1; ctx->show_text = 1;
ctx->mode = 0; ctx->mode = 0;
ctx->use_rotation_basis = 1; ctx->use_rotation_basis = 0;
ctx->limit_with_lines = 0; ctx->limit_with_lines = 1;
ctx->use_repelling = 0; ctx->use_repelling = 0;
ctx->show_marking = 0; ctx->show_marking = 1;
ctx->marking.x = -0.73679; ctx->marking.x = -0.73679;
ctx->marking.y = -0.01873; ctx->marking.y = -0.01873;
ctx->show_coxeter_orbit = 0; ctx->show_coxeter_orbit = 0;
@ -64,8 +50,8 @@ void setupContext(DrawingContext *ctx, int argc, char *argv[])
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*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, 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);
@ -84,30 +70,21 @@ void destroyContext(DrawingContext *ctx)
workspace_free(ctx->ws); workspace_free(ctx->ws);
} }
void computeMatrix(DrawingContext *ctx, gsl_matrix *result, const char *type) void computeRotationMatrix(DrawingContext *ctx, gsl_matrix *result, const char *type)
{
gsl_matrix **gen = getTempMatrices(ctx->ws, 6);
// ERROR(strlen(type) != 2, "Invalid call of computeRotationMatrix()\n");
initializeTriangleGeneratorsCurrent(gen, ctx);
gsl_matrix_set_identity(result);
for(int i = 0; i < strlen(type); i++) {
if(type[i] >= 'a' && type[i] <= 'c')
multiply_right(result, gen[type[i]-'a'], ctx->ws);
else if(type[i] >= 'A' && type[i] <= 'C')
multiply_right(result, gen[type[i]-'A'+3], ctx->ws);
}
releaseTempMatrices(ctx->ws, 6);
}
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); gsl_matrix **gen = getTempMatrices(ctx->ws, 3);
// ERROR(strlen(type) != 2, "Invalid call of computeRotationMatrix()\n");
initializeTriangleGenerators(gen, ctx->cartan);
gsl_matrix_set_identity(tmp);
for(int i = 0; i < strlen(type); i++)
multiply_right(tmp, gen[type[i]-'a'], ctx->ws);
rotation_frame(tmp, result, ctx->ws); rotation_frame(tmp, result, ctx->ws);
releaseTempMatrices(ctx->ws, 1);
releaseTempMatrices(ctx->ws, 4);
} }
void computeBoxTransform(DrawingContext *ctx, char *word1, char *word2, gsl_matrix *result) void computeBoxTransform(DrawingContext *ctx, char *word1, char *word2, gsl_matrix *result)
@ -167,9 +144,8 @@ void updateMatrices(DrawingContext *ctx)
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 % nmodes == 0) { if(ctx->use_rotation_basis % 5 == 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);
@ -180,25 +156,15 @@ void updateMatrices(DrawingContext *ctx)
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 % nmodes == 1) { } else if(ctx->use_rotation_basis % 5 == 1) {
gsl_matrix_set(tmp, 0, 0, 1.0);
gsl_matrix_set(tmp, 0, 1, -1.0);
gsl_matrix_set(tmp, 0, 2, 0.0);
gsl_matrix_set(tmp, 1, 0, 1.0);
gsl_matrix_set(tmp, 1, 1, 1.0);
gsl_matrix_set(tmp, 1, 2, 0.0);
gsl_matrix_set(tmp, 2, 0, 0.0);
gsl_matrix_set(tmp, 2, 1, 0.0);
gsl_matrix_set(tmp, 2, 2, 1.0);
gsl_matrix_memcpy(ctx->cob, ctx->cartan); // is this a good choice of basis for any reason? gsl_matrix_memcpy(ctx->cob, ctx->cartan); // is this a good choice of basis for any reason?
multiply_left(tmp, ctx->cob, ctx->ws); } else if(ctx->use_rotation_basis % 5 == 2) {
} else if(ctx->use_rotation_basis % nmodes == 2) { computeRotationMatrix(ctx, tmp, "ba");
computeRotationMatrixFrame(ctx, tmp, "C");
invert(tmp, ctx->cob, ctx->ws); invert(tmp, ctx->cob, ctx->ws);
} else if(ctx->use_rotation_basis % nmodes == 3) { } else if(ctx->use_rotation_basis % 5 == 3) {
computeBoxTransform(ctx, "acb", "cba", ctx->cob); computeBoxTransform(ctx, "bca", "abc", ctx->cob);
// computeBoxTransform(ctx, "cab", "bca", ctx->cob); // computeBoxTransform(ctx, "cab", "bca", ctx->cob);
// computeBoxTransform(ctx, "acb", "cba", ctx->cob); // computeBoxTransform(ctx, "acb", "cba", ctx->cob);
} else { } else {
cartanMatrix(tmp, M_PI/ctx->p[0], M_PI/ctx->p[1], M_PI/ctx->p[2], 1.0); 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); diagonalize_symmetric_form(tmp, ctx->cob, ctx->ws);
@ -258,7 +224,7 @@ int processEvent(GraphicsInfo *info, XEvent *ev)
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:
@ -282,34 +248,22 @@ int processEvent(GraphicsInfo *info, XEvent *ev)
switch(key) { switch(key) {
case XK_Down: case XK_Down:
if(ev->xkey.state & ShiftMask)
screen_context->parameter /= exp(0.00005);
else
screen_context->parameter /= exp(0.002); screen_context->parameter /= exp(0.002);
updateMatrices(screen_context); updateMatrices(screen_context);
computeLimitCurve(screen_context); computeLimitCurve(screen_context);
break; break;
case XK_Up: case XK_Up:
if(ev->xkey.state & ShiftMask)
screen_context->parameter *= exp(0.00005);
else
screen_context->parameter *= exp(0.002); screen_context->parameter *= exp(0.002);
updateMatrices(screen_context); updateMatrices(screen_context);
computeLimitCurve(screen_context); computeLimitCurve(screen_context);
break; break;
case XK_Left: case XK_Left:
if(ev->xkey.state & ShiftMask) screen_context->parameter /= exp(0.00002);
screen_context->parameter2 /= exp(0.00005);
else
screen_context->parameter2 /= exp(0.002);
updateMatrices(screen_context); updateMatrices(screen_context);
computeLimitCurve(screen_context); computeLimitCurve(screen_context);
break; break;
case XK_Right: case XK_Right:
if(ev->xkey.state & ShiftMask) screen_context->parameter *= exp(0.00002);
screen_context->parameter2 *= exp(0.00005);
else
screen_context->parameter2 *= exp(0.002);
updateMatrices(screen_context); updateMatrices(screen_context);
computeLimitCurve(screen_context); computeLimitCurve(screen_context);
break; break;
@ -329,7 +283,7 @@ int processEvent(GraphicsInfo *info, XEvent *ev)
computeLimitCurve(screen_context); computeLimitCurve(screen_context);
break; break;
case XK_Return: case XK_Return:
// screen_context->parameter = 2.76375163; // screen_context->parameter = 2.76375163;
screen_context->parameter = 5.29063366; screen_context->parameter = 5.29063366;
updateMatrices(screen_context); updateMatrices(screen_context);
computeLimitCurve(screen_context); computeLimitCurve(screen_context);
@ -378,18 +332,37 @@ int processEvent(GraphicsInfo *info, XEvent *ev)
print(screen_context); print(screen_context);
break; break;
case 'M': case 'M':
/*
screen_context->limit_with_lines = 0; screen_context->limit_with_lines = 0;
double parameter_start = screen_context->parameter; double parameter_start = screen_context->parameter;
double parameter2_start = screen_context->parameter2; for(int i = 0; i <= 1300; i++) {
for(int i = 0; i <= screen_context->movie_n_frames; i++) { if(i < 400)
screen_context->parameter = SIGN(parameter_start)*exp(log(fabs(parameter_start)) + screen_context->parameter = exp(log(parameter_start)+0.002*i);
i*screen_context->movie_parameter_duration/screen_context->movie_n_frames); else if(i < 500)
screen_context->parameter2 = SIGN(parameter2_start)*exp(log(fabs(parameter2_start)) + screen_context->parameter = exp(log(parameter_start)+0.002*400);
i*screen_context->movie_parameter2_duration/screen_context->movie_n_frames); else
screen_context->parameter = exp(log(parameter_start)+0.002*(900-i));
updateMatrices(screen_context); updateMatrices(screen_context);
computeLimitCurve(screen_context); computeLimitCurve(screen_context);
draw(screen_context); draw(screen_context);
sprintf(filename, "output/%s%03d.png", screen_context->movie_filename, i); sprintf(filename, "movie3/test%03d.png", i);
cairo_surface_write_to_png(info->buffer_surface, filename);
printf("Finished drawing %s\n", filename);
}
*/
screen_context->limit_with_lines = 0;
double parameter_start = screen_context->parameter;
for(int i = 0; i <= 1300; i++) {
if(i < 400)
screen_context->parameter = exp(0.003*i);
else if(i < 500)
screen_context->parameter = exp(0.003*400);
else
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); cairo_surface_write_to_png(info->buffer_surface, filename);
printf("Finished drawing %s\n", filename); printf("Finished drawing %s\n", filename);
} }
@ -428,14 +401,14 @@ int main(int argc, char *argv[])
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;

19
main.h
View File

@ -11,12 +11,7 @@
#define ERROR(condition, msg, ...) if(condition){fprintf(stderr, msg, ##__VA_ARGS__); exit(1);} #define ERROR(condition, msg, ...) if(condition){fprintf(stderr, msg, ##__VA_ARGS__); exit(1);}
#define LOOP(i) for(int i = 0; i < 3; i++) #define LOOP(i) for(int i = 0; i < 3; i++)
#define NUM_GROUP_ELEMENTS 10000 #define NUM_GROUP_ELEMENTS 50000
#define NUM_GROUP_ELEMENTS_COMBINATORIAL 100000
// (0,1) -> 2, (1,2) -> 0, (2,0) -> 1
// (1,0) -> 5, (2,1) -> 3, (0,2) -> 4
#define ROTATION_LETTER(x,y) (((y)-(x)+3)%3 == 1 ? ((y)+1)%3 : ((x)+1)%3+3)
typedef struct { typedef struct {
double x[3]; double x[3];
@ -35,13 +30,7 @@ typedef struct {
// a priori parameter // a priori parameter
int p[3],k[3]; int p[3],k[3];
double parameter; double parameter;
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 show_boxes; int show_boxes;
int show_boxes2; int show_boxes2;
int show_attractors; int show_attractors;
@ -77,8 +66,7 @@ typedef enum {
// implemented in limit_set.c // implemented in limit_set.c
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, double a1, double a2, double a3, double s, double t, workspace_t *ws); void initializeTriangleGenerators(gsl_matrix **gen, gsl_matrix *cartan);
void initializeTriangleGeneratorsCurrent(gsl_matrix **gen, DrawingContext *ctx);
int computeLimitCurve(DrawingContext *ctx); int computeLimitCurve(DrawingContext *ctx);
// implemented in draw.c // implemented in draw.c
@ -108,8 +96,7 @@ void setupContext(DrawingContext *ctx, int argc, char *argv[]);
void destroyContext(DrawingContext *ctx); void destroyContext(DrawingContext *ctx);
void print(DrawingContext *screen); void print(DrawingContext *screen);
int processEvent(GraphicsInfo *info, XEvent *ev); int processEvent(GraphicsInfo *info, XEvent *ev);
void computeMatrix(DrawingContext *ctx, gsl_matrix *result, const char *type); void computeRotationMatrix(DrawingContext *ctx, gsl_matrix *result, const char *type);
void computeRotationMatrixFrame(DrawingContext *ctx, gsl_matrix *result, const char *type);
void updateMatrices(DrawingContext *ctx); void updateMatrices(DrawingContext *ctx);
static vector_t vectorFromGsl(gsl_vector *v) static vector_t vectorFromGsl(gsl_vector *v)

View File

@ -14,7 +14,6 @@ typedef struct _groupelement {
struct _groupelement *parent; struct _groupelement *parent;
struct _groupelement *inverse; struct _groupelement *inverse;
int letter; int letter;
int visited;
} groupelement_t; } groupelement_t;
int generate_triangle_group(groupelement_t *group, int size, int k1, int k2, int k3); int generate_triangle_group(groupelement_t *group, int size, int k1, int k2, int k3);