Wie kann ich in Asymptote aus Teilen einer Formel einen Pfeil erstellen? (oder: Breite eines Etiketts messen, Anker um ein Etikett legen)

Wie kann ich in Asymptote aus Teilen einer Formel einen Pfeil erstellen? (oder: Breite eines Etiketts messen, Anker um ein Etikett legen)

Zusammenfassend: Ich möchte die folgende Figur in Asymptote zeichnen.

Bild

Mein Code ist wie folgt.

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.

Problem: In den 3 drawZeilen sind die x-Koordinaten der Startpunkte der Pfeile fest codiert.

Wie kann ich aus der Position der Spitze der Unterstrebe automatisch die Position des Pfeilanfangs berechnen?

(Die Möglichkeit, die Breite des Etiketts zu berechnen, wäre hilfreich, aber ich weiß auch nicht, wie das geht.)

Etwas Ähnliches wie die tikzmarkFunktion inhttps://tex.stackexchange.com/a/145696/250119würde helfen, aber mir ist keine solche Funktion in Asymptote bekannt.

Antwort1

Teillösung. Etwas adaptiert vonhttps://sourceforge.net/p/asymptote/discussion/409349/thread/3fc73fb8/.

Wenn man darüber nachdenkt, wird die Größe des Etiketts relativ zur Benutzerkoordinate erst ganz am Ende des Programms bestimmt --- was definitiv ein Problem darstellt. Dies ist also nur eine Teillösung, diees wird angenommen, dass unitsizees behoben ist.

Grundsätzlich werden 5 Beschriftungsobjekte erstellt, dann wird jedes Objekt in ein eingefügt und pictureanschließend seine Größe mit gemessen, min()/max()/size()um den Mittelpunkt der Unterkante der Box zu bestimmen.

Beachten Sie, dass das Unterbild richtig eingestellt sein muss , damit min()der richtige Wert usw. zurückgegeben wird .unitsize()

Bedauerlicherweise,Diese Methode stört den Abstand--- Ich bin nicht sicher, wie es behoben werden kann.

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);

Ausgabe:Asymptotenausgabe

verwandte Informationen