Asymptote で数式の一部から矢印を作成するにはどうすればよいでしょうか? (または、ラベルの幅を測定し、ラベルの周りにアンカーを取得します)

Asymptote で数式の一部から矢印を作成するにはどうすればよいでしょうか? (または、ラベルの幅を測定し、ラベルの周りにアンカーを取得します)

要約: Asymptote で次の図を描きたいです。

画像

私のコードは次のとおりです。

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.

問題: 3draw行で、矢印の開始点の x 座標がハードコードされています。

アンダーブレースの先端の位置から矢印の開始位置を自動的に計算するにはどうすればよいですか?

(ラベルの幅を計算できれば役立つのですが、その方法もわかりません。)

tikzmarkに示された機能に似たものhttps://tex.stackexchange.com/a/145696/250119役立つと思いますが、Asymptote にそのような機能があるかどうかはわかりません。

答え1

部分的な解決策。https://sourceforge.net/p/asymptote/discussion/409349/thread/3fc73fb8/

考えてみれば、ラベルのサイズはユーザー座標に対してプログラムが最後まで決定されないので、間違いなく問題が生じます。したがって、これは部分的な解決策に過ぎません。unitsize固定されていると仮定する

基本的に、5 つのラベル オブジェクトを作成し、各オブジェクトを に配置してpicture、 でサイズを測定し、min()/max()/size()ボックスの下端の中点を決定します。

min()などが正しい値を返すようにするには、unitsize()サブピクチャのが正しく設定されている必要があることに注意してください。

残念ながら、この方法は間隔を乱す--- どうすれば直せるのか分かりません。

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

出力:漸近線出力

関連情報