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.

문제: 3 draw줄에 화살표 시작점의 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);

산출:점근선 출력

관련 정보