.png)
En resumen: quiero dibujar la siguiente figura en asíntota.
Mi código es el siguiente.
size(5cm);
draw(scale(8, 4)*unitsquare);
label("$\underbrace{123}+\underbrace{456}=\underbrace{789}$", (4, 3));
draw((2.1, 2.5)--(1, 1), Arrow);
draw((3.95, 2.5)--(4, 1), Arrow);
draw((5.9, 2.5)--(7, 1), Arrow);
label("\strut$a$", (1, 1.1), S);
label("\strut$b$", (4, 1.1), S);
label("\strut$c$", (7, 1.1), S); // \strut is used to make the baselines horizontally aligned.
Problema: en las 3 draw
líneas, la coordenada x del punto inicial de las flechas está codificada.
¿Cómo puedo calcular automáticamente la ubicación del inicio de la flecha desde la posición de la punta del soporte?
(Sería útil poder calcular el ancho de la etiqueta, pero tampoco veo cómo).
Algo similar a la tikzmark
característica que se muestra enhttps://tex.stackexchange.com/a/145696/250119Sería útil, pero no conozco ninguna característica de este tipo en Asymptote.
Respuesta1
Solución parcial. Algo adaptado dehttps://sourceforge.net/p/asymptote/discussion/409349/thread/3fc73fb8/.
Si lo piensas bien, el tamaño de la etiqueta en relación con las coordenadas del usuario no se determina hasta el final del programa, lo que definitivamente causa un problema. Entonces, esta es sólo una solución parcial quese supone unitsize
que está arreglado.
Básicamente, construye 5 objetos de etiqueta, luego, para cada objeto, se coloca en un picture
, luego se mide su tamaño min()/max()/size()
para determinar el punto medio del borde inferior de la caja.
Tenga en cuenta que para que min()
etc. devuelva el valor correcto, unitsize()
la imagen secundaria debe estar configurada correctamente.
Desafortunadamente,este método altera el espaciado--- No estoy seguro de cómo se puede solucionar.
var unitsize=1cm;
unitsize(unitsize);
string template="$\underbrace{1}$";
picture a;
unitsize(a, unitsize);
// draw the labels, and compute the coordinate of the bottom points along the way
label(a, baseline("$\underbrace{123}$", template), (0, 0), align=NE);
pair bottom1=((min(a, user=true).x+max(a, user=true).x)/2, min(a, user=true).y);
label(a, baseline("$+$", template), (max(a, user=true).x, 0), align=NE);
real u=max(a, user=true).x;
label(a, baseline("$\underbrace{456}$", template), (max(a, user=true).x, 0), align=NE);
pair bottom2=((u+max(a, user=true).x)/2, min(a, user=true).y);
label(a, baseline("$=$", template), (max(a, user=true).x, 0), align=NE);
real u=max(a, user=true).x;
label(a, baseline("$\underbrace{789}$", template), (max(a, user=true).x, 0), align=NE);
pair bottom3=((u+max(a, user=true).x)/2, min(a, user=true).y);
// compute shift such that the text is centered at x = 4
pair ashift=(4-size(a, user=true).x/2, 3);
// draw the text on currentpicture
add(shift(ashift)*a);
// some other text for comparison
label("$\underbrace{123}+\underbrace{456}=\underbrace{789}$", (4, 4), align=N);
label("$123+456=789$", (4, 5), align=N);
// draw the arrows
draw(ashift+bottom1--(1, 1), Arrow);
draw(ashift+bottom2--(4, 1), Arrow);
draw(ashift+bottom3--(7, 1), Arrow);
label(baseline("$a$"), (1, 1.1), S);
label(baseline("$b$"), (4, 1.1), S);
label(baseline("$c$"), (7, 1.1), S);