\n", CONV(x1), CONV(y1),
+ poincare_arc(x1, y1, x2, y2, buffer), arguments);
#else
printf("\\draw[%s] (%f, %f) -- (%f, %f);\n", arguments, x1, y1, x2, y2);
#endif
}
-int main()
+void compute_word(workspace_t *ws, gsl_matrix *result, gsl_matrix **gen, const char *word, int modifier)
+{
+ gsl_matrix_set_identity(result);
+ for(int i = 0; word[i] != 0; i++)
+ multiply_right(result, gen[(word[i]-'a'+modifier)%3], ws);
+}
+
+int main(int argc, const char *argv[])
{
groupelement_t *group;
gsl_matrix **matrices;
gsl_matrix *cartan;
gsl_matrix *gen[3];
gsl_matrix *coxeter[3];
+ gsl_matrix *coxeter2[3];
gsl_matrix *coxeter_eigenvectors[3];
+ gsl_matrix *coxeter_eigenvectors2[3];
gsl_matrix *frame;
workspace_t *ws;
- int elements = 2000;
- int p = 4, q = 4, r = 4;
+
+ if(argc < 5) {
+ fprintf(stderr, "Usage: %s \n", argv[0]);
+ exit(1);
+ }
+
+ int elements = atoi(argv[4]);
+ int p = atoi(argv[1]), q = atoi(argv[2]), r = atoi(argv[3]);
group = malloc(elements*sizeof(groupelement_t));
matrices = malloc(elements*sizeof(gsl_matrix*));
@@ -203,6 +254,8 @@ int main()
LOOP(i) gen[i] = gsl_matrix_alloc(3, 3);
LOOP(i) coxeter[i] = gsl_matrix_alloc(3, 3);
LOOP(i) coxeter_eigenvectors[i] = gsl_matrix_alloc(3, 3);
+ LOOP(i) coxeter2[i] = gsl_matrix_alloc(3, 3);
+ LOOP(i) coxeter_eigenvectors2[i] = gsl_matrix_alloc(3, 3);
ws = workspace_alloc(3);
generate_triangle_group(group, elements, p, q, r);
@@ -214,8 +267,16 @@ int main()
for(int i = 1; i < elements; i++)
multiply(matrices[group[i].parent->id], gen[group[i].letter], matrices[i]);
- LOOP(i) multiply_many(ws, coxeter[i], 3, gen[i%3], gen[(i+1)%3], gen[(i+2)%3]);
+// LOOP(i) multiply_many(ws, coxeter[i], 3, gen[i%3], gen[(i+1)%3], gen[(i+2)%3]); // coxeter
+// LOOP(i) multiply_many(ws, coxeter[i], 4, gen[i%3], gen[(i+1)%3], gen[i%3], gen[(i+2)%3]); // abcb
+ LOOP(i) compute_word(ws, coxeter[i], gen, "abcb", i);
+/* LOOP(i) multiply_many(ws, coxeter[i], 10,
+ gen[i%3], gen[(i+1)%3], gen[(i+2)%3],
+ gen[i%3], gen[(i+1)%3], gen[(i+2)%3],
+ gen[i%3], gen[(i+1)%3], gen[(i+2)%3],
+ gen[(i+1)%3]); // (abc)^3 b */
LOOP(i) eigenvectors(coxeter[i], coxeter_eigenvectors[i], ws);
+ LOOP(i) eigenvectors(coxeter2[i], coxeter_eigenvectors2[i], ws);
/*
for(int i = 0; i < elements; i++) {
@@ -230,12 +291,19 @@ int main()
point coxeter_attracting[3];
point coxeter_repelling[3];
point coxeter_axes[3];
+ point coxeter2_attracting[3];
+ point coxeter2_repelling[3];
+ point coxeter2_axes[3];
point edge_midpoints[3];
point reflection_lines[3];
point triangle_points[3];
point transformed[3];
point transformed2[3];
point transformed3[3];
+ point transformed4[3];
+ point transformed5[3];
+ point transformed6[3];
+ point center;
LOOP(i) coxeter_attracting[i] = column(coxeter_eigenvectors[i], 0);
LOOP(i) coxeter_repelling[i] = column(coxeter_eigenvectors[i], 2);
@@ -243,8 +311,35 @@ int main()
LOOP(i) edge_midpoints[i] = incidence(coxeter_axes[(i+1)%3], coxeter_axes[(i+2)%3]);
LOOP(i) reflection_lines[i] = row(cartan, i);
LOOP(i) triangle_points[i] = incidence(reflection_lines[(i+1)%3], reflection_lines[(i+2)%3]);
+ LOOP(i) coxeter2_attracting[i] = column(coxeter_eigenvectors2[i], 0);
+ LOOP(i) coxeter2_repelling[i] = column(coxeter_eigenvectors2[i], 2);
+ LOOP(i) coxeter2_axes[i] = incidence(coxeter2_attracting[i], coxeter2_repelling[i]);
- print_tex_header();
+ print_svg_header();
+
+ // let's correct the frame of reference by using hyperbolic transformations
+ center = apply(frame, triangle_points[2]);
+ double angle = atan2(center.x[1], center.x[0]);
+ double boost = atanh(-sqrt(center.x[0]*center.x[0]+center.x[1]*center.x[1])/center.x[2]);
+ gsl_matrix *frame_correction = gsl_matrix_alloc(3, 3);
+ gsl_matrix_set_identity(frame_correction);
+
+ /*
+ gsl_matrix_set(frame_correction, 0, 0, cos(angle-M_PI/2));
+ gsl_matrix_set(frame_correction, 0, 1, sin(angle-M_PI/2));
+ gsl_matrix_set(frame_correction, 1, 0, -sin(angle-M_PI/2));
+ gsl_matrix_set(frame_correction, 1, 1, cos(angle-M_PI/2));
+ gsl_matrix_set(frame_correction, 2, 2, 1);
+// multiply_left(frame_correction, frame, ws);
+ gsl_matrix_set_identity(frame_correction);
+ gsl_matrix_set(frame_correction, 0, 0, cosh(-boost));
+ gsl_matrix_set(frame_correction, 0, 2, sinh(-boost));
+ gsl_matrix_set(frame_correction, 1, 1, 1);
+ gsl_matrix_set(frame_correction, 2, 0, sinh(-boost));
+ gsl_matrix_set(frame_correction, 2, 2, cosh(-boost));
+ multiply_left(frame_correction, frame, ws);
+ */
+ gsl_matrix_free(frame_correction);
// int indices[10] = {0, 1, 6, 10, 30, 46, 124, 185, 484, 717};
// int indices[10] = {0, 1, 4, 10, 22};
@@ -254,16 +349,69 @@ int main()
continue;
LOOP(i) transformed[i] = apply(matrices[k], triangle_points[i]);
- draw_triangle(transformed, frame, "black,fill=black!10,line width=0pt");
+// draw_triangle(transformed, frame, "black,fill=black!10,line width=0pt");
+ draw_triangle(transformed, frame, "fill:#cfcfcf;");
+// draw_triangle(transformed, frame, "fill:#000000;");
}
- for(int k = 0; k < 2000; k++) {
- if(group[k].length % 2)
- continue;
+ for(int k = 0; k < elements; k++) {
+// if(group[k].length % 2)
+// continue;
- LOOP(i) transformed[i] = apply(matrices[k], coxeter_attracting[i]);
+ LOOP(i) transformed[i] = apply(matrices[k], edge_midpoints[(i+2)%3]);
+ LOOP(i) transformed2[i] = apply(matrices[k], coxeter_repelling[i]);
+ LOOP(i) transformed3[i] = apply(matrices[k], coxeter_repelling[(i+1)%3]);
+ LOOP(i) transformed4[i] = apply(matrices[k], coxeter_attracting[i%3]);
+ LOOP(i) transformed5[i] = apply(matrices[k], coxeter2_repelling[i]);
+ LOOP(i) transformed6[i] = apply(matrices[k], coxeter2_attracting[i%3]);
+ //LOOP(i) draw_line(transformed2[i], transformed4[i], frame, "red");
+ draw_line(transformed2[0], transformed4[0], frame, "fill:none;stroke:red;stroke-width:1;");
+// draw_line(transformed2[1], transformed4[1], frame, "fill:none;stroke:blue;stroke-width:1;");
+// draw_line(transformed2[2], transformed4[2], frame, "fill:none;stroke:darkgreen;stroke-width:1;");
+
+// draw_line(transformed5[0], transformed6[0], frame, "fill:none;stroke:blue;stroke-width:1;");
+// draw_line(transformed5[1], transformed6[1], frame, "fill:none;stroke:blue;stroke-width:1;");
+// draw_line(transformed5[2], transformed6[2], frame, "fill:none;stroke:blue;stroke-width:1;");
+// draw_line(transformed2[1], transformed4[1], frame, "fill:none;stroke:darkgreen;stroke-width:1;");
+// draw_line(transformed2[2], transformed4[2], frame, "fill:none;stroke:blue;stroke-width:1;");
+// LOOP(i) draw_line(transformed[i], transformed3[i], frame, "red");
+
+// LOOP(i) transformed[i] = apply(matrices[k], coxeter_attracting[i]);
// draw_line(transformed[1], transformed[2], frame, "red");
}
- print_tex_footer();
+ /*
+ draw_line(apply(matrices[0], coxeter_repelling[0]),
+ apply(matrices[0], coxeter_attracting[0]),
+ frame, "fill:none;stroke:red;stroke-width:1;");
+ draw_line(apply(matrices[1], coxeter_repelling[0]),
+ apply(matrices[1], coxeter_attracting[0]),
+ frame, "fill:none;stroke:red;stroke-width:1;");
+ draw_line(apply(matrices[2], coxeter_repelling[0]),
+ apply(matrices[2], coxeter_attracting[0]),
+ frame, "fill:none;stroke:red;stroke-width:1;");
+ draw_line(apply(matrices[3], coxeter_repelling[0]),
+ apply(matrices[3], coxeter_attracting[0]),
+ frame, "fill:none;stroke:red;stroke-width:1;");
+ draw_line(apply(matrices[4], coxeter_repelling[0]),
+ apply(matrices[4], coxeter_attracting[0]),
+ frame, "fill:none;stroke:red;stroke-width:1;");
+ draw_line(apply(matrices[5], coxeter_repelling[0]),
+ apply(matrices[5], coxeter_attracting[0]),
+ frame, "fill:none;stroke:red;stroke-width:1;");
+ draw_line(apply(matrices[14], coxeter_repelling[0]),
+ apply(matrices[14], coxeter_attracting[0]),
+ frame, "fill:none;stroke:red;stroke-width:1;");
+ draw_line(apply(matrices[15], coxeter_repelling[0]),
+ apply(matrices[15], coxeter_attracting[0]),
+ frame, "fill:none;stroke:red;stroke-width:1;");
+ draw_line(apply(matrices[22], coxeter_repelling[0]),
+ apply(matrices[22], coxeter_attracting[0]),
+ frame, "fill:none;stroke:red;stroke-width:1;");
+ draw_line(apply(matrices[23], coxeter_repelling[0]),
+ apply(matrices[23], coxeter_attracting[0]),
+ frame, "fill:none;stroke:red;stroke-width:1;");
+ */
+
+ print_svg_footer();
}