/* Tools for drawing figures for the FMC book */ /* Last edited on 2024-12-21 14:02:29 by stolfi */ #ifndef fmc_book_tools_H #define fmc_book_tools_H #include #include #include #include #include #include #include typedef struct ptset_t { char *name; /* Data set name for file names. */ char *label; /* Data set name to be printed on figure. */ r3_vec_t p; /* Relative coordinates and numeric label of points. */ r2_t szLab; /* Max nominal width and height of point labels (mm). */ r2_t pMin; /* Min {X} and {Y} point coordinates. */ r2_t pMax; /* Max {X} and {Y} point coordinatesaxs. */ } ptset_t; /* Description of a point set and its looks. */ ptset_t make_ptset(char *name, char *label, int32_t n, r3_t q[], r2_t *szLab); /* The points {q[0..n-1]} should be triples {(xk,yk,labk)} where {(xk,yk)} are coordinates in multiples of a "standard point spacing". They are converted to actual coordinates in mm by the procedure. */ typedef struct relac_t { char *name; /* Relation name for file names. */ char *label; /* Relation name to be printed on figure. */ bool_t cal; /* True for calligraphic font, false for roman. */ i2_vec_t R; /* List of pairs of point indices. */ double labwd; /* Nominal print width of relaton {label} (mm). */ double dxinv; /* {X} displacement for the "-1" superscript. */ } relac_t; /* Description of a relation (set of arrows). */ relac_t make_relac(char *name, char *label, bool_t cal, int32_t n, i2_t R[], double labwd, double dxinv); epswr_figure_t *open_fig(char *fname, double xSize, double ySize); void draw_fig_relac_setas(ptset_t *sA, ptset_t *sB, relac_t *r, bool_t inv); void draw_fig_relac_pontos(ptset_t *sA, ptset_t *sB, relac_t *r); void draw_fig_compos_setas(ptset_t *sA, ptset_t *sB, ptset_t *sC, relac_t *rR, relac_t *rS, bool_t inv); void draw_arrows ( epswr_figure_t *eps, ptset_t *sA, r2_t *dpA, ptset_t *sB, r2_t *dpB, relac_t *r, double dxName, bool_t inv ); /* Draws a set of relation arrows from the dots specidied in {sA} to those specified in {sB}. Namely draws an arrow from dot {(xA[kA],yA[kA])} to dot {(xB[kB],yB[kB])} for every pair {(kA,kB)} in {R[0..n-1]}; where {xA[k],yA[k]} are the first two coordinates of {sA.p.e[k]} displaced by {dpA}, and ditto for {xB[k],yB[k]} and {dpB}. If {nv} is true, the arrows are reversed so that they point to the {sB.p} points to the {sA.p} points. The origin and destination dots are overpainted in red to highlight the domain and image of the relation. If {Rlabel} is not null or empty, prints it at the top of the arrow bunch. ??? INV*/ void draw_pair_dots ( epswr_figure_t *eps, ptset_t *sA, r2_t *dpA, ptset_t *sB, r2_t *dpB, relac_t *r ); /* Draws dots at intersections. ??? Complete ??? */ void draw_set_vert(epswr_figure_t *eps, ptset_t *s, r2_t *dp, sign_t labdir); /* Draws an oval with a vertical row of labaled dots inside. The elements of {s.p.e[0..s.p.ne-1]} are triples {(x,y,lab)} where {lab} is an integer value that will be printed as label with format %.0f". next to the point. The {x} coordinates of the points should be all equal. Each dot dot will be plotted at coordinates {(x,y)} which should be in mm. The whole plot will be shifted so that the low corner of the bounding box of all dots will be at {dp}. The dot labels will be placed to the left of the dots if {dir} is -1,to their right if {dir} is {+1}, and above if {dir} is zero. The procedure assumes that the largest label has size {s.szLab} (mm). If {s->label} is not null or empty, prints it above the set's outline. */ void draw_set_horz(epswr_figure_t *eps, ptset_t *s, r2_t *dp); /* Draws an oval with a horizontal row of labaled dots inside. The elements of {s.p.e[0..s.p.ne-1]} are triples {(x,y,lab)} where {lab} is an integer value that will be printed as label with format %.0f". next to the point. The {x} coordinates should be all equal. The dot will be placed at coordinates {(y,x)} (note the order!) which should be in {mm}. The set of dots will be flipped left to right and the whole plot will be shifted so that the low corner of the bounding box of all dots will be at {dp}. The dot label will be placed below each dot. The procedure assumes that the largest label has size {s.szLab} (mm). If {s->label} is not null or empty, prints it to the right of the set's outline. */ /* DEBUG TOOLS: */ void draw_label_corners(epswr_figure_t *eps, r2_t *pLab, r2_t *align, r2_t *szLab); /* Draw dots at the presumed corners of a label, given its reference point {pLab}, the alignment parameters {align}, and the nominal size {szLab}. All coordinates and dimensions are in {mm}. */ void show_i2(char *Rname, int32_t n, i2_t R[]); void show_r3(char *pname, r3_vec_t p); #define mm (72.0/25.4) /* Points per mm. */ #define fmc_font_size (8.0) /* Nominal font height (mm) */ #define fmc_dot_radius (1.0) /* Nominal dot radius in {mm} */ #define fmc_digit_width (0.55*fmc_font_size) /* Estimated digit width (mm). */ #endif