#ifndef TRIANGLE_GROUP_MAIN_H #define TRIANGLE_GROUP_MAIN_H #include "triangle.h" #include "linalg.h" #include "initcairo.h" #undef ERROR #define ERROR(condition, msg, ...) if(condition){fprintf(stderr, msg, ##__VA_ARGS__); exit(1);} #define LOOP(i) for(int i = 0; i < 3; i++) #define NUM_GROUP_ELEMENTS 50000 #define MAX_TEMP_MATRICES 60000 #define MAX_TEMP_VECTORS 100 typedef struct { double x[3]; } vector_t; typedef struct { double x; double y; } point_t; typedef struct { // infos about the screen to draw on cairo_t *cairo; DimensionsInfo *dim; // a priori parameter int p[3],k[3]; double parameter; int n_group_elements; int show_boxes; int show_attractors; int show_reflectors; int show_limit; int limit_with_lines; int use_repelling; gsl_matrix *cartan, *cob; // precomputed and constant groupelement_t *group; // computed stuff double *limit_curve; // x, y, angle triples int limit_curve_valid; // temporary; matrices can only be freed from the top, but that's enough for us workspace_t *ws; gsl_matrix **tmp; int tmp_used; gsl_vector **tmp_vec; int tmp_vec_used; } DrawingContext; static gsl_matrix **getTempMatrices(DrawingContext *ctx, int n) { ERROR(ctx->tmp_used + n > MAX_TEMP_MATRICES, "Ran out of temporary matrices. Consider increasing MAX_TEMP_MATRICES\n"); int index = ctx->tmp_used; ctx->tmp_used += n; return ctx->tmp + index; } static gsl_matrix *getTempMatrix(DrawingContext *ctx) { return *getTempMatrices(ctx, 1); } static void releaseTempMatrices(DrawingContext *ctx, int n) { ERROR(ctx->tmp_used - n < 0, "Released more matrices then in use\n"); ctx->tmp_used -= n; } static gsl_vector **getTempVectors(DrawingContext *ctx, int n) { ERROR(ctx->tmp_vec_used + n > MAX_TEMP_VECTORS, "Ran out of temporary vectors. Consider increasing MAX_TEMP_VECTORS\n"); int index = ctx->tmp_vec_used; ctx->tmp_vec_used += n; return ctx->tmp_vec + index; } static gsl_vector *getTempVector(DrawingContext *ctx) { return *getTempVectors(ctx, 1); } static void releaseTempVectors(DrawingContext *ctx, int n) { ERROR(ctx->tmp_vec_used - n < 0, "Released more vectors then in use\n"); ctx->tmp_vec_used -= n; } // implemented in limit_set.c void cartanMatrix(gsl_matrix *cartan, double a1, double a2, double a3, double s); void initializeTriangleGenerators(gsl_matrix **gen, gsl_matrix *cartan); int computeLimitCurve(DrawingContext *ctx); // implemented in draw.c vector_t cross(vector_t a, vector_t b); int fixedPoints(DrawingContext *ctx, const char *word, vector_t *out); void drawPoint(DrawingContext *ctx, point_t p); void drawSegment2d(DrawingContext *ctx, point_t a, point_t b); void drawVector(DrawingContext *ctx, vector_t v); void drawCovector(DrawingContext *ctx, vector_t v); void drawSegment(DrawingContext *ctx, vector_t a, vector_t b); void drawPolygon(DrawingContext *ctx, int sides, ...); void drawTriangle(DrawingContext *ctx, const char *word); void drawBox(DrawingContext *ctx, const char *word1, const char *word2); void drawBoxStd(DrawingContext *ctx, const char *word, char base); void drawReflectors(DrawingContext *ctx); void drawAttractors(DrawingContext *ctx); void drawBoxes(DrawingContext *ctx); void drawLimitCurve(DrawingContext *ctx); void drawText(DrawingContext *ctx); void draw(DrawingContext *ctx); // implemented in main.c void setupContext(DrawingContext *ctx); void destroyContext(DrawingContext *ctx); void print(DrawingContext *screen); int processEvent(GraphicsInfo *info, XEvent *ev); void updateMatrices(DrawingContext *ctx); #endif