Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
treepic_utils.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
44# ifndef TREEPIC_UTILS_H
45# define TREEPIC_UTILS_H
46
47# include <cstdio>
48# include <cmath>
49
50# include <cstdlib>
51# include <cstring>
52# include <iostream>
53# include <fstream>
54
55# include <aleph.H>
56
57const long double sin_45 = sin(M_PI_4);
58const long double cos_45 = cos(M_PI_4);
59
60const char * const font_wrapper = "\\texttt{";
61const char * fill_type = "shade";
62
63static const long double points_per_inch = 72.27;
64static const long double mm_per_inch = 25.4;
65
66long double font_width_in_points = 5;
67
68long double font_width_in_mm =
70long double font_height_in_mm = 2.0;
71
72long double resolution = 0.05; /* resolution en milimetros */
73
74bool flip_y = false;
75
76bool tiny_keys = false;
77
78
79extern const long double sin_45;
80extern const long double cos_45;
81
82extern std::string input_file_name;
83extern std::string output_file_name;
84
85
86extern const char * const font_wrapper;
87extern const char * fill_type;
88
89extern long double resolution;
90extern long double font_width_in_mm;
91extern long double font_height_in_mm;
92extern long double font_width_in_points;
93
94extern long double resolution; /* resolution en milimetros */
95extern double v_size;
96
97//extern bool tiny_keys;
98
99/* ancho de letra en puntos segun resolucion */
100inline long double font_width()
101{
103}
104
105
106inline long double font_height()
107{
109}
110
111
112
113/*
114 calcula los puntos de interseccion entre una recta y una elipse. La
115 recta pasa por el punto central de la elipse.
116
117 lx0, ly0 : punto centro de la elipse y primer punto de la recta
118 lx1, ly1 : segundo punto de la recta
119 a,b parametros de elipse (x - lx0)^2/a^2 + y - ly0)^2/b^2
120
121 dx, dy son las diferencias en x e y de los puntos de interseccion
122*/
123inline void
124intersection_ellipse_line(long double lx0, // puntos recta
125 long double ly0,
126 long double lx1,
127 long double ly1,
128 long double a, // parametros elipse (centro lx0,ly0)
129 long double b,
130 long double & dx,
131 long double & dy) /* Diferencias respecto al
132 centro de la elipse */
133{
134 long double m = (1.0*(ly1 - ly0)) / (1.0*(lx1 - lx0));
135 long double m2 = m*m;
136 long double a2 = a*a;
137 long double b2 = b*b;
138 long double R = m2 + b2/a2;
139 long double L = lx0*lx0 - b2/R;
140 long double S = 1.0/m2 + a2/b2;
141 long double M = ly0*ly0 - a2/S;
142
143 long double x0_2 = 2.0*lx0;
144 long double xdisc = sqrt(4.0*lx0*lx0 - 4.0*L);
145
146 long double ix0 = (x0_2 + xdisc) / 2.0;
147
148 dx = ix0 - lx0;
149 assert(dx >= 0);
150
151 long double y0_2 = 2.0*ly0;
152 long double ydisc = sqrt(4.0*ly0*ly0 - 4.0*M);
153
154 long double iy0 = (y0_2 - ydisc) / 2.0;
155
156 dy = ly0 - iy0;
157 assert(dy >= 0);
158}
159
160
161inline void
162intersection_line_line(long double lx1, // puntos recta 1
163 long double ly1,
164 long double lx2,
165 long double ly2,
166 long double rx1, // puntos recta 2
167 long double ry1,
168 long double rx2,
169 long double ry2,
170 long double & x,
171 long double & y)
172{
173 long double lm = (ly2 - ly1)/(lx2 - lx1); // pendiente recta l
174 long double rm = (ry2 - ry1)/(rx2 - rx1); // pendiente recta r
175
176 x = (lm*lx1 - rm*rx1 + ry1 - ly1)/(lm - rm);
177
178 long double lm_inv = 1/lm; // inversa pendiente recta l
179 long double rm_inv = 1/rm; // inversa pendiente recta r
180
181 y = (lm_inv*ly1 - rm_inv*ry1 + rx1 - lx1)/(lm_inv - rm_inv);
182}
183
184
185inline long double distance_between_points(long double x1,
186 long double y1,
187 long double x2,
188 long double y2)
189{
190 long double a = x2 - x1;
191 long double b = y2 - y1;
192
193 return sqrt(a*a + b*b);
194}
195
196/*
197 calcula los puntos de interseccion entre una recta y un
198 rectangulo. La recta pasa por el punto central del rectangulo.
199
200 lx0, ly0 : punto centro del rectangulo y primer punto de la recta
201 lx1, ly1 : segundo punto de la recta
202 a,b radios horizontal y vertical del rectangulo
203
204 dx, dy son las diferencias en x e y de los puntos de interseccion
205*/
206inline void
207intersection_rectangle_line(long double lx0, // puntos recta
208 long double ly0,
209 long double lx1,
210 long double ly1,
211 long double a, // radio hor (centro lx0,ly0)
212 long double b, // radio ver
213 long double & dx,
214 long double & dy) /* Diferencias respecto al
215 centro rectangulo */
216{
217 assert(a >= 0);
218 assert(b >= 0);
219
220 /* La intersección requiere considerar intersección con dos rectas
221 del rectangulo: la horizontal y la vertical */
222
223 // diferencia con punto de interseccion con recta horizontal
224 long double dxh = b * ((lx1 - lx0)/(ly1 - ly0));
225 long double dyh = b;
226
227 // diferencia con punto de interseccion con recta vertical
228 long double dxv = a;
229 long double dyv = a * ((ly1 - ly0)/(lx1 - lx0));
230
231 /* calcular distancias desde centro rectangulo hasta los puntos de
232 interseccion. El punto será el correspondiente a la menor
233 distancia. Para ello calculamos cuadrados de hipotenusas según el
234 milenario Pitágoras y comparamos */
235 if (dxh*dxh + dyh*dyh < dxv*dxv + dyv*dyv)
236 {
237 dx = std::fabs(dxh);
238 dy = b;
239 }
240 else
241 {
242 dx = a;
243 dy = std::fabs(dyv);
244 }
245}
246
247extern bool flip_y;
248
249inline long double YPIC(long double y)
250{
251 return flip_y ? y : v_size - y;
252}
253
254
255inline size_t compute_true_len(const std::string & str)
256{
257 const char * ptr = str.c_str();
258
259 for (int i = 0, counter = 0; true; /* empty */)
260 {
261 switch (ptr[i])
262 {
263 case '\\':
264 for (i++; isalnum(ptr[i]) and ptr[i] not_eq '\0'; /* nothing */)
265 i++;
266 counter++;
267 break;
268 case '$': case '{': case '}': case '\n':
269 i++;
270 break;
271 case '\0':
272 return counter;
273 default:
274 counter++; i++;
275 break;
276 }
277 }
278}
279
280
281inline void put_string(std::ofstream& output,
282 const long double& x, const long double& y,
283 const std::string & comment, const std::string & str)
284{
285 if (str.size() == 0)
286 return;
287
288 output << std::endl
289 << "% " << comment << std::endl
290 << "\\put(" << x << ","
291 /* Se ajusta la posicion y del caracter segun si la
292 impresion es flip o no */
293 << (flip_y ? YPIC(y) - font_height() : YPIC(y))
294 << "){" ;
295 if (tiny_keys)
296 output << font_wrapper << "{\\tiny " << str << "}}}" << std::endl << std::endl;
297 else
298 output << font_wrapper << str << "}}" << std::endl << std::endl;
299}
300
301inline void put_string_tkiz(std::ofstream& output,
302 const long double& x, const long double& y,
303 const std::string & comment, const std::string & str)
304{
305 if (str.size() == 0)
306 return;
307
308 output << std::endl
309 << "% " << comment << std::endl
310 << "\\draw (" << x << "mm,"
311 /* Se ajusta la posicion y del caracter segun si la
312 impresion es flip o no */
313 << (flip_y ? YPIC(y) - font_height() : YPIC(y))
314 << "mm) node { " << str << " }" << std::endl << std::endl;
315}
316
320static long double arrow_width_in_mm = 0.5;
321static long double arrow_lenght_in_mm = 1.5;
323bool with_arrow = false;
324long double dash_len = 1/resolution; // 1m
327
328inline void draw_arc(std::ofstream& output,
329 long double src_x, long double src_y,
330 long double tgt_x, long double tgt_y,
331 bool is_dashed, bool with_arrow, [[maybe_unused]] bool thick = true)
332{
333 if (is_dashed)
334 output << "\\dashline{" << dash_len << "}(";
335 else
336 output << "\\drawline(";
337 output << src_x << "," << YPIC(src_y) << ")("
338 << tgt_x << "," << YPIC(tgt_y) << ")";
339
340 if (not with_arrow)
341 return;
342
344 long double tetha = atan2(arrow_width, arrow_lenght);
345 long double phi = atan( std::fabs( (tgt_y - src_y)/(tgt_x - src_x) ) );
346
347 long double dx1 = l*cos(phi - tetha);
348 long double dy1 = l*sin(phi - tetha);
349
350 long double dx2 = l*sin(M_PI_2 - (phi + tetha));
351 long double dy2 = l*cos(M_PI_2 - (phi + tetha));
352
353 if (tgt_x > src_x)
354 {
355 dx1 = -dx1;
356 dx2 = -dx2;
357 }
358
359 if (tgt_y > src_y)
360 {
361 dy1 = -dy1;
362 dy2 = -dy2;
363 }
364
365 output << std::endl
366 << "\\path(" << tgt_x << "," << YPIC(tgt_y) << ")("
367 << tgt_x + dx1 << "," << YPIC(tgt_y + dy1) << ")" << std::endl
368 << "\\path(" << tgt_x << "," << YPIC(tgt_y) << ")("
369 << tgt_x + dx2 << "," << YPIC(tgt_y + dy2) << ")" << std::endl << std::endl;
370}
371
372inline void draw_arc_tikz(std::ofstream& output,
373 long double src_x, long double src_y,
374 long double tgt_x, long double tgt_y,
375 bool is_dashed, bool with_arrow, [[maybe_unused]] bool thick = true)
376{
377 if (is_dashed)
378 output << "\\draw[dashed] (";
379 else
380 output << "\\draw (";
381 output << src_x << "mm," << YPIC(src_y) << "mm) -- ("
382 << tgt_x << "mm," << YPIC(tgt_y) << "mm) ;";
383
384 if (not with_arrow)
385 return;
386
388 long double tetha = atan2(arrow_width, arrow_lenght);
389 long double phi = atan( std::fabs( (tgt_y - src_y)/(tgt_x - src_x) ) );
390
391 long double dx1 = l*cos(phi - tetha);
392 long double dy1 = l*sin(phi - tetha);
393
394 long double dx2 = l*sin(M_PI_2 - (phi + tetha));
395 long double dy2 = l*cos(M_PI_2 - (phi + tetha));
396
397 if (tgt_x > src_x)
398 {
399 dx1 = -dx1;
400 dx2 = -dx2;
401 }
402
403 if (tgt_y > src_y)
404 {
405 dy1 = -dy1;
406 dy2 = -dy2;
407 }
408
409 output << std::endl
410 << "\\draw (" << tgt_x << "," << YPIC(tgt_y) << ") -- ("
411 << tgt_x + dx1 << "mm," << YPIC(tgt_y + dy1) << "mm) ; " << std::endl
412 << "\\draw (" << tgt_x << "mm," << YPIC(tgt_y) << "mm) -- ("
413 << tgt_x + dx2 << "mm," << YPIC(tgt_y + dy2) << "mm) ; " << std::endl << std::endl;
414}
415
416/*
417 Esta rutina estima el offset x donde se debe colocar la cadena str
418 en una ventana de ancho window_size */
419inline long double center_string(const std::string& str, [[maybe_unused]] long double window_size)
420{
421 return compute_true_len(str)*font_width();
422}
423
424
425/* calcula la longitud de la cadena en puntos segun la resolucion */
426inline long double string_width(const std::string& str)
427{
428 return compute_true_len(str)*font_width();
429}
430
431
432inline int compute_section(long double x1, long double y1,
433 long double x2, long double y2)
434{
435 if (x2 > x1 and y2 > y1)
436 return 0;
437
438 if (x2 < x1 and y2 > y1)
439 return 1;
440
441 // en este punto y2 < y1
442
443 return x2 > x1 ? 3 : 2;
444}
445
446
447/* Dados dos puntos (sx,sy) y (tx,ty) calcula el punto (mx,my) situado
448 perpendicularmente sobre la recta */
449inline void
450compute_mid_point_line(const long double & sx, const long double & sy,
451 const long double & tx, const long double & ty,
452 const long double & d,
453 [[maybe_unused]] const bool & left,
454 long double & mx, long double & my)
455{
456 const long double lx = fabsl(tx - sx);
457 const long double ly = fabsl(ty - sy);
458
459 const long double h = sqrtl(lx*lx + ly*ly); // longitud del segmento
460 // (sx,sy) --> (tx,ty)
461
462 const long double h2 = h/2; // mitad del segmento
463
464 const long double alpha = atanl(ly/lx); // ángulo del segmento
465 // respecto al eje x
466
467 const long double beta = atanl(d/h2); // ángulo entre el segmento
468 // y la recta que estaría
469 // entre (sx,sy) y (mx,my)
470
471 const long double hp = sqrtl(d*d + h2*h2); // longitud del segmento
472 // (sx,sy) --> (mx,my)
473
474 const long double ab = alpha + beta; // ángulo del segmento
475 // (sx,sy)-->(mx,my) respecto al
476 // eje x
477
478 const long double dx = hp*cosl(ab);
479 const long double dy = hp*sinl(ab);
480
481 // coordenadas del punto normalizadas a un segmento apuntando
482 // hacia el noroeste
483 mx = tx - dx;
484 my = dy;
485}
486
487
488# endif // TREEPIC_UTILS_H
Core header for the Aleph-w library.
long double h
Definition btreepic.C:154
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_y1_function > > y1(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4103
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_cos_function > > cos(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4069
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_sin_function > > sin(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4070
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_sqrt_function > > sqrt(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4058
__gmp_expr< typename __gmp_resolve_expr< T, V >::value_type, __gmp_binary_expr< __gmp_expr< T, U >, __gmp_expr< V, W >, __gmp_atan2_function > > atan2(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Definition gmpfrxx.h:4078
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_atan_function > > atan(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4077
static mpfr_t y
Definition mpfr_mul_d.c:3
DynList< int > l
void intersection_ellipse_line(long double lx0, long double ly0, long double lx1, long double ly1, long double a, long double b, long double &dx, long double &dy)
const char *const font_wrapper
const long double cos_45
long double resolution
void put_string(std::ofstream &output, const long double &x, const long double &y, const std::string &comment, const std::string &str)
int compute_section(long double x1, long double y1, long double x2, long double y2)
long double font_height_in_mm
void draw_arc_tikz(std::ofstream &output, long double src_x, long double src_y, long double tgt_x, long double tgt_y, bool is_dashed, bool with_arrow, bool thick=true)
void compute_mid_point_line(const long double &sx, const long double &sy, const long double &tx, const long double &ty, const long double &d, const bool &left, long double &mx, long double &my)
bool tiny_keys
Global flag to enable tiny font size for keys/labels.
std::string input_file_name
Definition btreepic.C:406
long double string_width(const std::string &str)
void put_string_tkiz(std::ofstream &output, const long double &x, const long double &y, const std::string &comment, const std::string &str)
void intersection_line_line(long double lx1, long double ly1, long double lx2, long double ly2, long double rx1, long double ry1, long double rx2, long double ry2, long double &x, long double &y)
long double arrow_lenght
long double font_width_in_points
bool with_arrow
long double distance_between_points(long double x1, long double y1, long double x2, long double y2)
static const long double points_per_inch
bool flip_y
long double dash_len
void draw_arc(std::ofstream &output, long double src_x, long double src_y, long double tgt_x, long double tgt_y, bool is_dashed, bool with_arrow, bool thick=true)
double v_size
Definition btreepic.C:156
static const long double mm_per_inch
void intersection_rectangle_line(long double lx0, long double ly0, long double lx1, long double ly1, long double a, long double b, long double &dx, long double &dy)
std::string output_file_name
Definition btreepic.C:407
long double font_width()
long double arrow_width
const char * fill_type
static long double arrow_lenght_in_mm
static long double arrow_width_in_mm
long double font_height()
long double font_width_in_mm
size_t compute_true_len(const std::string &str)
long double YPIC(long double y)
long double center_string(const std::string &str, long double window_size)
const long double sin_45
ofstream output
Definition writeHeap.C:213