¿Cómo puedo hacer una flecha a partir de partes de una fórmula en asíntota? (o: medir el ancho de una etiqueta, anclar alrededor de una etiqueta)

¿Cómo puedo hacer una flecha a partir de partes de una fórmula en asíntota? (o: medir el ancho de una etiqueta, anclar alrededor de una etiqueta)

En resumen: quiero dibujar la siguiente figura en asíntota.

imagen

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 drawlí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 tikzmarkcaracterí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 unitsizeque 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);

Producción:salida asíntota

información relacionada