这个 Asymptote 代码中的 `align` 参数起什么作用?

这个 Asymptote 代码中的 `align` 参数起什么作用?

以下代码产生输出

picture pic1;
size(pic1,10);
fill(pic1,(0,0)--(5,10)--(10,0)--cycle,red+opacity(0.5)); // triangle

picture pic2;
size(pic2,10);
fill(pic2,unitcircle,green+opacity(0.5)); // circle

picture pic;
add(pic,pic1.fit(),position = (0,0));
add(pic,pic2.fit(),position = (0,0));

add(pic.fit());

在此处输入图片描述

但是,如果我将该行更改add(pic,pic1.fit(),position = (0,0));为, add(pic,pic1.fit(),position = (0,0),align=N);我会得到输出

在此处输入图片描述

我预计红色三角形会从第一张图片中的位置稍微向北移动。我在理解函数行为时哪里出了错?

答案1

align事实上,几个月前我就开始写一些测试例子了(因为你的问题图片的.fit()方法有什么作用?)。Asymptote 论坛帮助中也有一个关于某些行为的讨论。请找一些解释、代码、图片。希望它能帮助 Asymptote 用户。

测试 1:简单,pic.fit()align参数

从左到右、从上到下。pic1创建一张图片(使用keepAspect=false),并添加各种pic.fit(x.size, y.size,keepAspect)

情况 1 :pic1在 (1.2,.5) 坐标点添加。无额外参数

情况 2 :pic1.fit(2*xs,ys,keepAspect=true)。由于keepAspect=true pic1 未缩放(选择最小值)

情况 3 :pic1放大 2 pic1.fit(2*xs,ys)。由于keepAspect=false (pic1 的精度)y坐标未缩放

情况 3 :pic1.fit(2*xs,3*ys,keepAspect=true) pic1按比例缩放(x并且 `y 乘以 2=min(2,3))

在情况 3 和 4 中,值得注意的是固定大小的对象(标签、线宽)不缩放。还请注意的坐标(0,0)pic1左下角。

size(10cm);

picture pic1;
size(pic1,2cm,keepAspect=false);
label(pic1,"T",(.5,.5));
label(pic1,"O",(1,1),SW);
draw(pic1,unitsquare);
draw(pic1,(.5,.5)--(1,1));

frame f1=pic1.fit();
dot((.5,1.2),blue);
add(f1,(.5,1.2));

real xs=pic1.xsize;
real ys=pic1.ysize;

frame f2=pic1.fit(2*xs,ys,keepAspect=true);
add(f2,(1.5,1.2));
dot((1.5,1.2),blue);

frame f3=pic1.fit(2*xs,ys);
add(f3,(.5,.5));
dot((.5,.5),blue);

frame f4=pic1.fit(2*xs,3*ys,keepAspect=true);
add(f4,(1.5,.5));
dot((1.5,.5),blue);

在此处输入图片描述

测试 2:pic.fit()align参数

对于第一个测试,(0,0)的坐标pic1不是左下角(矩形被移位)。如 Asymptote 文档中所述,pic1将对齐,以便原点位于(.5,1)当前图片的位置(此处)。(参见案例 1 和 2)

情况 1:未给出选项。的原点pic1位于(.5,1)当前图片的位置。

情况 2:pair align给出选项:(0,0)。然后pic1对齐,使得的中心pic1位于(.9,1)当前图片的位置。

情况 3:根据文档,常数Align可用于在位置 处对齐标签的左下角。 Alignpair,因此使用+/-Align.x+/-Align.y我们可以pic1 在 {Left/Mid/Right}/{Top/Mid/Bottom} 点处对齐。这里pair align=(Align.x,0)position=(.5,.7)。这意味着 pic1将在 方向上对齐(Align.x,0)(相当于(1,0))并从 偏移position=(.5,.7)PostScript偏移量(Align.x,0)*labelmargin(p)

情况 4:情况 3 的另一个例子,对齐到 的边界点pic2add(f4,(1,.9),(-2*Align.x,-5*Align.y))。绿线添加到pic1以获得pic2pair l=truepoint(pic2,(2,5))允许将点放置在边界上。 遵循文档truepoint(picture pic=currentpicture, pair dir, bool user=true) 是一种方便的方法,可以确定 pic 边界框上相对于其中心(这里包括固定大小的对象)沿 dir 方向的点。

案例 5:Align.x值为 1.05367121277235e-08。如果值更大会发生什么?我们在这里选择add(f5,(.5,.7),(10,15))。按照文档,它将沿着 方向对齐,并按 PostScript 偏移量(10,15)偏离(当前图片) 。为了说明获得的 边界点,添加了一条线 :允许绘制一个固定大小的对象(在 PostScript 坐标中,(0,0)--(10,15) 线)关于用户坐标原点。值得注意的是,红线和蓝线有一个共同的端点。(.5,.7)(10,15)*labelmargin(p)pic2draw((.5,.7),(0,0)--(10,15),linecap(0)+red)(.5,.7)

案例 6:与案例 5 类似,位置以厘米为单位。您可以验证从点到左下角的距离是否等于 2cm。

size(9cm);

picture pic1;
size(pic1,3cm);
label(pic1,"T",(.5,.5));
label(pic1,"O",(1,1),SW);
draw(pic1,shift(0,.2)*scale(2,1)*unitsquare);
draw(pic1,(.5,.5)--(1,1));

frame f1=pic1.fit();

add(f1,(.5,1));
dot((.5,1));

add(f1,(.9,1.05),(0,0));
dot((.9,1.05));

add(f1,(.5,.9),(Align.x,0));
dot((.5,.9));

picture pic2;
size(pic2,3cm);
add(pic2,pic1);
pair l=truepoint(pic2,(2,5));
draw(pic2,l--(l.x,.5),green+linecap(0));
frame f4=pic2.fit();
add(f4,(1,.95),(-2*Align.x,-5*Align.y));
dot((1,.95));

pair l=truepoint(pic1,(-10,-15));
draw(pic1,l--(l.x,.5),blue+linecap(0));
frame f5=pic1.fit();
dot((.5,.7));
add(f5,(.5,.7),(10,15));
write(labelmargin(currentpen));
draw((.5,.7),(0,0)--(10,15),linecap(0)+red);

add(f1,(.75,.7),1cm*unit((1,1)));
dot((.75,.7));
draw((.75,.7),(0,0)--1cm*unit((1,1)),linecap(0)+red);

在此处输入图片描述

测试 3:add(pic1)vs add(pic1.fit()),缩放

情况1:无选项无位置。add(pic1)相当于将绘制命令应用pic1 到当前图片

情况 2:没有给出任何选项,只有位置(4,.5)。惊喜!添加的图片很小!事实上,正如文档中提到的,add(pic1,(4,.5))将把 Postcript 坐标中指定的坐标添加pic1到当前图片中。

pic1.fit情况 3:位置处的标准(0,2)

情况 4:通过以适当的值缩放pic1到,我们在位置 处得到 的等价物。值得注意的是,固定缩放对象(标签)不缩放。pic2pic1.fit(3,-2)

情况 5:图片在 x 方向上按 y 方向缩放 3 倍pic1。固定缩放对象(标签)不缩放。

情况 6:在 x 方向上按因子 3 缩放pic1.fit()。固定缩放的对象(标签、线宽)按 x- 缩放。*/

size(8cm);

//label("Picture test",(1,1));
draw(shift(3,-2)*scale(8)*shift((-.5,-.5))*unitsquare);

/*
Last test: the difference between scaling/adding picture to picture and frame to picture.
*/ 

picture pic1;
size(pic1,2cm);
label(pic1,"T",(.5,.5));
label(pic1,"O",(1,1),SW);
draw(pic1,scale(2,1)*unitsquare);
draw(pic1,(.5,.5)--(1,1));

add(pic1);
/* is equivalent to
  label("T",(.5,.5));
  label("O",(1,1),SW);
  draw(scale(2,1)*unitsquare);
  draw((.5,.5)--(1,1));
*/
dot((0,0),blue); // is at the origin of `add(pic1)`

add(pic1,(4,.5)); // so small

frame f1=pic1.fit();
add(f1,(0,-2));


picture pic2;
pic2=(scale(size(pic1).x/size(pic1,user=true).x)*pic1);
add(currentpicture,pic2,(3,-2));


picture pic3;
pic3=(scale(3*size(pic1).x/size(pic1,user=true).x,size(pic1).x/size(pic1,user=true).x)*pic1);
add(currentpicture,pic3,(0,-3.5));


frame f1=pic1.fit();
add(scale(3,1)*f1,(0,-5));

在此处输入图片描述

相关内容