diff --git a/draw.c b/draw.c index 5a66ca0..17cb4b0 100644 --- a/draw.c +++ b/draw.c @@ -96,7 +96,7 @@ void drawPoint(DrawingContext *ctx, point_t p) cairo_t *C = ctx->cairo; cairo_save(C); - cairo_arc(C, p.x, p.y, 5.0/ctx->dim->scalefactor, 0, 2*M_PI); + cairo_arc(C, p.x, p.y, 3.0/ctx->dim->scalefactor, 0, 2*M_PI); cairo_close_path(C); cairo_fill(C); cairo_restore(C); @@ -198,11 +198,20 @@ void drawSegmentWith(DrawingContext *ctx, vector_t a, vector_t b, vector_t line, } // t = parameter on segment of intersection with line, s(t) = a + (b-a)*t - tline = (a_.x*x[0] + a_.y*x[1] + x[2])/((b_.x - a_.x)*x[0] + (b_.y - a_.y)*x[1]); + tline = -(a_.x*x[0] + a_.y*x[1] + x[2])/((b_.x - a_.x)*x[0] + (b_.y - a_.y)*x[1]); + + /* + printf("tline: %f\n", tline); + + point_t s; + s.x = a_.x - (b_.x-a_.x)*tline; + s.y = a_.y - (b_.y-a_.y)*tline; + drawPoint(ctx, s); + */ if((tline < 0 || tline > 1) != contains) { drawSegment2d(ctx, a_, b_); - } else { // need to draw complementary semgent + } else { // need to draw complementary segment // find t so that s(t) is at radius r from center, |s(t)-m| = r m.x = ctx->dim->center_x; m.y = ctx->dim->center_y; @@ -613,7 +622,7 @@ char *conjugate_word(const char *word, int modifier, const char *conj, char *buf void drawCurvedBox(DrawingContext *ctx, int base, const char *conj, int style) { - vector_t p[10][3]; + vector_t p[11][3]; vector_t l[2][3]; vector_t corner1, corner2; vector_t tmp1, tmp2; @@ -640,6 +649,9 @@ void drawCurvedBox(DrawingContext *ctx, int base, const char *conj, int style) fixedPoints(ctx, word, p[8]); conjugate_word("bacabab", modifier, conj, word); fixedPoints(ctx, word, p[9]); + conjugate_word("cab", modifier, conj, word); + fixedPoints(ctx, word, p[10]); + // conjugate_word("bca b abc b acb", modifier, conj, word); // fixedPoints(ctx, word, p[6]); @@ -649,12 +661,13 @@ void drawCurvedBox(DrawingContext *ctx, int base, const char *conj, int style) LOOP(j) l[0][j] = cross(p[0][(3-j)%3], p[0][(4-j)%3]); LOOP(j) l[1][j] = cross(p[1][(3-j)%3], p[1][(4-j)%3]); + LOOP(j) l[10][j] = cross(p[10][(3-j)%3], p[10][(4-j)%3]); // main conic conjugate_word("ab", modifier, conj, word); drawArcWithOutput(ctx, word, p[0][0], VT_POINT, p[2][0], VT_POINT, p[1][0], 0, &tmp1, &tmp2, style != 1); if(style == 2) - drawSegment(ctx, tmp1, tmp2); + drawSegmentWith(ctx, tmp1, tmp2, l[10][0], 0); if(style == 3) { drawVector(ctx, tmp1); drawVector(ctx, tmp2); @@ -663,7 +676,7 @@ void drawCurvedBox(DrawingContext *ctx, int base, const char *conj, int style) conjugate_word("ab", modifier, conj, word); drawArcWithOutput(ctx, word, p[1][0], VT_POINT, p[3][0], VT_POINT, p[0][0], 0, &tmp1, &tmp2, style != 1); if(style == 2) - drawSegment(ctx, tmp1, tmp2); + drawSegmentWith(ctx, tmp1, tmp2, l[10][0], 0); if(style == 3) { drawVector(ctx, tmp1); drawVector(ctx, tmp2); @@ -672,14 +685,14 @@ void drawCurvedBox(DrawingContext *ctx, int base, const char *conj, int style) conjugate_word("bcabcb", modifier, conj, word); drawArcWithOutput(ctx, word, p[2][0], VT_POINT, l[1][0], VT_LINE, p[6][0], 1, &tmp1, &tmp2, style != 1); // only 1st cutoff if(style == 2) - drawSegment(ctx, tmp1, tmp2); + drawSegmentWith(ctx, tmp1, tmp2, l[10][0], 0); corner1 = tmp2; conjugate_word("abcabcba", modifier, conj, word); drawArcWithOutput(ctx, word, p[3][0], VT_POINT, l[0][0], VT_LINE, p[7][0], 1, &tmp1, &tmp2, style != 1); // only 1st cutoff if(style == 2) - drawSegment(ctx, tmp1, tmp2); + drawSegmentWith(ctx, tmp1, tmp2, l[10][0], 0); corner2 = tmp2; if(style == 1 || style == 2) { @@ -721,12 +734,12 @@ void drawBoxes(DrawingContext *ctx) drawRotationOrbit(ctx, "ca", p[0][0]); 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 + 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 } cairo_set_source_rgb(C, 1, 0, 1); @@ -931,48 +944,99 @@ void drawBoxes2(DrawingContext *ctx) cairo_set_source_rgb(C, 0, 0, 1); // drawCurvedBox(ctx, 'C', "ab", 2); - cairo_set_source_rgb(C, 0, 0.8, 0.5); // drawCurvedBox(ctx, 'C', "ab", 2); // drawCurvedBox(ctx, 'B', "bca", 2); - drawCurvedBox(ctx, 'B', "ba", 2); - drawCurvedBox(ctx, 'B', "bca", 2); - drawCurvedBox(ctx, 'B', "abca", 2); +// drawCurvedBox(ctx, 'B', "ba", 2); +// drawCurvedBox(ctx, 'B', "bca", 2); +// drawCurvedBox(ctx, 'B', "abca", 2); // drawCurvedBox(ctx, 'C', "abab", 2); // drawCurvedBox(ctx, 'C', "ababab", 2); - if(ctx->mode >= 4) { + if(ctx->mode >= 3 && ctx->mode != 4) { + cairo_set_source_rgb(C, 0, 0, 0); + drawCurvedBox(ctx, 'B', "", 2); + drawCurvedBox(ctx, 'C', "", 2); + } + + if(ctx->mode == 4 || ctx->mode == 5) { + cairo_set_source_rgb(C, 0, 0.8, 0.5); + drawCurvedBox(ctx, 'A', "", 2); + drawCurvedBox(ctx, 'A', "bc", 2); + drawCurvedBox(ctx, 'A', "bcbc", 2); + drawCurvedBox(ctx, 'A', "bcbcbc", 2); + drawCurvedBox(ctx, 'A', "bcbcbcbc", 2); + drawCurvedBox(ctx, 'A', "bcbcbcbcbc", 2); + drawCurvedBox(ctx, 'A', "bcbcbcbcbcbc", 2); +// drawCurvedBox(ctx, 'A', "b", 2); +// drawCurvedBox(ctx, 'A', "bcb", 2); +// drawCurvedBox(ctx, 'A', "bcbcb", 2); +// drawCurvedBox(ctx, 'A', "bcbcbcb", 2); +// drawCurvedBox(ctx, 'A', "bcbcbcbcb", 2); + } + + if(ctx->mode == 6) { + cairo_set_source_rgb(C, 0, 0.8, 0.5); + drawCurvedBox(ctx, 'C', "abababab", 2); + drawCurvedBox(ctx, 'C', "ababababab", 2); + } + + if(ctx->mode >= 6) { + cairo_set_source_rgb(C, 0, 0.8, 0.5); + drawCurvedBox(ctx, 'C', "ab", 2); + drawCurvedBox(ctx, 'C', "abab", 2); + drawCurvedBox(ctx, 'C', "ababab", 2); + } + + if(ctx->mode >= 8) { + cairo_set_source_rgb(C, 0, 0.8, 0.5); drawCurvedBox(ctx, 'C', "b", 2); drawCurvedBox(ctx, 'C', "bab", 2); drawCurvedBox(ctx, 'C', "babab", 2); } - if(ctx->mode >= 5) { + if(ctx->mode >= 9) { cairo_set_source_rgb(C, 0.8, 0, 0.5); drawCurvedBox(ctx, 'B', "abca", 2); drawCurvedBox(ctx, 'B', "abcaca", 2); + drawCurvedBox(ctx, 'B', "abcacaca", 2); drawCurvedBox(ctx, 'B', "aba", 2); drawCurvedBox(ctx, 'B', "abaca", 2); + drawCurvedBox(ctx, 'B', "abacaca", 2); + drawCurvedBox(ctx, 'B', "ababca", 2); drawCurvedBox(ctx, 'B', "ababcaca", 2); + drawCurvedBox(ctx, 'B', "ababcacaca", 2); drawCurvedBox(ctx, 'B', "ababa", 2); drawCurvedBox(ctx, 'B', "ababaca", 2); + drawCurvedBox(ctx, 'B', "ababacaca", 2); + drawCurvedBox(ctx, 'B', "abababca", 2); drawCurvedBox(ctx, 'B', "abababcaca", 2); + drawCurvedBox(ctx, 'B', "abababcacaca", 2); drawCurvedBox(ctx, 'B', "abababa", 2); drawCurvedBox(ctx, 'B', "abababaca", 2); + drawCurvedBox(ctx, 'B', "abababacaca", 2); drawCurvedBox(ctx, 'B', "bca", 2); drawCurvedBox(ctx, 'B', "bcaca", 2); + drawCurvedBox(ctx, 'B', "bcacaca", 2); drawCurvedBox(ctx, 'B', "ba", 2); drawCurvedBox(ctx, 'B', "baca", 2); + drawCurvedBox(ctx, 'B', "bacaca", 2); + drawCurvedBox(ctx, 'B', "babca", 2); drawCurvedBox(ctx, 'B', "babcaca", 2); + drawCurvedBox(ctx, 'B', "babcacaca", 2); drawCurvedBox(ctx, 'B', "baba", 2); drawCurvedBox(ctx, 'B', "babaca", 2); + drawCurvedBox(ctx, 'B', "babacaca", 2); + drawCurvedBox(ctx, 'B', "bababca", 2); drawCurvedBox(ctx, 'B', "bababcaca", 2); + drawCurvedBox(ctx, 'B', "bababcacaca", 2); drawCurvedBox(ctx, 'B', "bababa", 2); drawCurvedBox(ctx, 'B', "bababaca", 2); + drawCurvedBox(ctx, 'B', "bababacaca", 2); } // drawCurvedBox(ctx, 'B', "abab", 2); @@ -1377,6 +1441,8 @@ void drawCoxeterOrbit(DrawingContext *ctx) gsl_vector *startpoint_coxeterbasis = getTempVector(ctx->ws); gsl_vector *startpoint_globalbasis = getTempVector(ctx->ws); gsl_vector *startpoint_drawbasis = getTempVector(ctx->ws); + gsl_matrix **elements = getTempMatrices(ctx->ws, ctx->n_group_elements); + cairo_t *C = ctx->cairo; vector_t cox[3][3]; vector_t abcb[3]; @@ -1388,7 +1454,7 @@ void drawCoxeterOrbit(DrawingContext *ctx) cairo_save(C); initializeTriangleGenerators(gen, ctx->cartan); - cairo_set_source_rgb(C, 1, 0, 1); + cairo_set_source_rgb(C, 0, 0, 1); fixedPoints(ctx, "abc", cox[0]); fixedPoints(ctx, "bca", cox[1]); @@ -1397,6 +1463,11 @@ void drawCoxeterOrbit(DrawingContext *ctx) wordEigenvalues(ctx, "abc", ev); LOOP(i) LOOP(j) gsl_matrix_set(coxeter_fixedpoints, j, i, cox[0][i].x[j]); + initializeTriangleGenerators(gen, ctx->cartan); + 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]); + //printf("coxeter eigenvalues: %f %f %f\n", ev[0], ev[1], ev[2]); // LOOP(i) gsl_vector_set(startpoint_globalbasis, i, cox[1][0].x[i]); @@ -1407,8 +1478,11 @@ void drawCoxeterOrbit(DrawingContext *ctx) solve(ctx->cob, startpoint_drawbasis, startpoint_globalbasis, 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); + + /* for(int t = -1000; t < 1000; t++) { LOOP(i) v.x[i] = 0; LOOP(i) LOOP(j) v.x[j] += pow(fabs(ev[i]),t*0.01)*start.x[i]*cox[0][i].x[j]; @@ -1422,18 +1496,28 @@ void drawCoxeterOrbit(DrawingContext *ctx) } } cairo_stroke(C); + */ - for(int t = -20; t < 20; t++) { + for(int i = 0; i < ctx->n_group_elements; i++) { + v = apply(elements[i], start); + drawVector(ctx, v); +// 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, 1, column)/gsl_matrix_get(fixedpoints_pos, 0, column)); + } + + +/* for(int t = -20; t < 20; t++) { LOOP(i) v.x[i] = 0; LOOP(i) LOOP(j) v.x[j] += (ev[i]<0&&t%2?-1:1)*pow(fabs(ev[i]),t/3.0)*start.x[i]*cox[0][i].x[j]; drawVector(ctx, v); - } + }*/ cairo_set_source_rgb(C, 0, 0, 0); - LOOP(i) drawVector(ctx, abcb[i]); +// LOOP(i) drawVector(ctx, abcb[i]); cairo_restore(C); - releaseTempMatrices(ctx->ws, 5); + releaseTempMatrices(ctx->ws, 5 + ctx->n_group_elements); releaseTempVectors(ctx->ws, 4); } @@ -1487,7 +1571,7 @@ void draw(DrawingContext *ctx) if(ctx->show_marking) { - cairo_set_source_rgb(C, 1, 0, 1); + cairo_set_source_rgb(C, 0, 0, 1); drawPoint(ctx, ctx->marking); } diff --git a/main.c b/main.c index ea62504..3803ced 100644 --- a/main.c +++ b/main.c @@ -35,12 +35,12 @@ void setupContext(DrawingContext *ctx, int argc, char *argv[]) ctx->show_attractors = 0; ctx->show_reflectors = 0; ctx->show_rotated_reflectors = 0; - ctx->show_limit= 1; + ctx->show_limit= 0; ctx->show_dual_limit= 0; ctx->show_text = 1; ctx->mode = 0; ctx->use_rotation_basis = 0; - ctx->limit_with_lines = 0; + ctx->limit_with_lines = 1; ctx->use_repelling = 0; ctx->show_marking = 1; ctx->marking.x = -0.73679; @@ -268,12 +268,12 @@ int processEvent(GraphicsInfo *info, XEvent *ev) computeLimitCurve(screen_context); break; case XK_Page_Down: - screen_context->parameter /= exp(0.2); + screen_context->parameter /= exp(0.02); updateMatrices(screen_context); computeLimitCurve(screen_context); break; case XK_Page_Up: - screen_context->parameter *= exp(0.2); + screen_context->parameter *= exp(0.02); updateMatrices(screen_context); computeLimitCurve(screen_context); break;