以下代码产生输出
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
可用于在位置 处对齐标签的左下角。
Align
为pair
,因此使用+/-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 的另一个例子,对齐到 的边界点pic2
。
add(f4,(1,.9),(-2*Align.x,-5*Align.y))
。绿线添加到pic1
以获得pic2
,
pair 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)
pic2
draw((.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
到,我们在位置 处得到 的等价物。值得注意的是,固定缩放对象(标签)不缩放。pic2
pic1.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));