![Asymptote 的错误](https://linux22.com/image/301573/Asymptote%20%E7%9A%84%E9%94%99%E8%AF%AF.png)
我正在尝试使用以下代码绘制一个简单的四面体(渐近线)
size(10cm,0);
import math;
import three;
import graph3;
currentprojection=perspective(1/3,-1,1/2);
real l2=sqrt(0.75);
triple x1=(0,0,0), x2=(1,0,0), x3=(0.5,l2,0);
draw(x1--x2--x3--cycle);
label("$x_1$",x1,W);
label("$x_2$",x2,E);
label("$x_3$",x3,NW);
dot(x1);dot(x2);dot(x3);
triple b3=(0.5,l2/2,0);
dot(b3,red);
label("$B_3$",b3,S,red);
real l3=sqrt( (5+4*l2*l2)/9 );
triple x4=(0.5,l2/2,l3);
draw(b3--x4,red);
label("$x_4$",x4,N,red);
draw(x4--x1,dashed);
draw(x4--x2,dashed);
draw(x4--x3,dashed);
使用 编译后,asy tetrahedron.asy
我得到的是一幅eps
图像,其中的线条x1--x2
不知为何变成了虚线,而使用 编译后,asy tetrahedron.asy -tex pdflatex
我得到的是一幅空白图像。tex.SE
不允许我上传任何一种格式的图像,但我可以使用用户可能要求的任何其他工具来共享它们。只需使用我应该使用的工具发表评论即可。
任何帮助都将不胜感激,以了解我为什么会收到这些错误,以及/或者如何修复我的脚本。
答案1
这条线不是虚线,只是渲染成那样。使用three
模块,Asymptote 可以生成栅格输出而不是向量输出。您可以使用选项增加分辨率(并减慢渲染所需的时间)-render
。输出的默认值为 2。eps
如果我稍微转动视角并使用 进行编译asy -render 7
,您的绘图在我的系统上看起来会更好。这里是使用
currentprojection=perspective(1,-1,1/2);
并使用 OSX Preview 转换为png
每英寸 142 像素。
如果您希望获得正确的矢量输出,那么您可能应该使用pstricks
,它可以很好地处理 3D(尽管大多数文档只有法语)。Metapost 是另一种产生矢量 PostScript 的替代方案,但没有标准的 3D 方法。您可以尝试 mp3d 或 mp-solid,但对于像四面体这样简单的东西,您所需要的只是一个将 3D 点投影到 2D 点的例程。像这样:
prologues := 3;
outputtemplate := "%j%c.eps";
vardef pp(expr xx,yy,zz) =
_x := yy*cosd(theta) - xx*sind(theta);
_y := zz*cosd(phi) - yy*sind(theta)*sind(phi) - xx*cosd(theta)*sind(phi);
_z := 12 - zz*sind(phi) - yy*sind(theta)*cosd(phi) - xx*cosd(theta)*cosd(phi);
1000*(_x/_z, _y/_z)
enddef;
theta := 288; % rotation of viewpoint
phi := 18; % elevation of viewpoint
beginfig(1);
z0 = pp(0,0,0);
z1 = pp(-sqrt(3)/2, -1/2, 0);
z2 = pp(+sqrt(3)/2, -1/2, 0);
z3 = pp(0,1,0);
z4 = pp(0,0,sqrt(2));
draw z1--z2--z3--cycle;
draw z0 -- z4 withcolor .67 red;
draw z1 -- z4 dashed evenly scaled .7;
draw z2 -- z4 dashed evenly scaled .7;
draw z3 -- z4 dashed evenly scaled .7;
dotlabel.lft (btex $x_1$ etex, z1);
dotlabel.rt (btex $x_2$ etex, z2);
dotlabel.ulft(btex $x_3$ etex scaled .8, z3);
dotlabel.top (btex $x_4$ etex, z4);
dotlabel.rt (btex $B_3$ etex, z0) withcolor .67 red;
endfig;
end.
优点是 (a) 它非常简单快捷,(b) 它是正确的矢量输出,因此没有锯齿状边缘。但仅此而已;PSTricks 或 Asymptote 在 3D 绘图的其他各个方面或多或少都会做得更好。
答案2
根据 Asymptote 的文档,有 3(或 4)种不同的方法来处理 3D
- PRC : pdf 输出,仅 Adobe Reader 支持。此外,3D 图片可通过 Adobe Reader 进行交互。
- 基于 OpenGL 的渲染器:
-V
选项。将打开一个 OpenGL 窗口,其中包含您的 3D 场景、交互式操作(更改视点、显示相机)、导出(位图) - 使用以前的 OpenGL 渲染器,
-render=n
每位图 n 个像素,png、pdf、eps 输出。某些 opengl 驱动程序/图形卡会出现一些问题(例如垂直线) render=0
:Asymptote 非常古老的 3D 模式。只有 3D 场景的 2D 投影,没有处理隐藏面的算法。但是向量化输出
对于这样的例子或一个非常简单的 3D 场景,您可以自行管理隐藏面、虚线段,asy -render=0
从而得到矢量化输出。当然,-render=0
对于 3D 来说,它非常有限(我记得有一些简单的固体包可以管理相对于相机的虚线/非虚线段)。
答案3
我清理了这篇旧帖子的代码。在法线通过点的transform3
方向上投影dir
到平面上的A返回的是n
O
transform3 planeproject(triple n, triple O=O, triple dir=n);
可以使用normal(path3 p)
来找到平面三维路径的单位法向量p
。在平面路径定义的平面transform3
方向上投影的A由以下公式返回dir
p
transform3 planeproject(path3 p, triple dir=normal(p));
在这种情况下,为了获得顶点x4
(视为特殊的path3
)在基平面上的正交投影x1--x2--x3
,我们使用
path3 base=x1--x2--x3;
triple b3=planeproject(base,normal(base))*x4;
// http://asymptote.ualberta.ca/
unitsize(1cm);
import three;
size(6cm);
currentprojection=perspective(1/3,-1,1/2);
real l2=sqrt(0.75);
real l3=sqrt( (5+4*l2*l2)/9 );
triple x1=(0,0,0), x2=(1,0,0), x3=(0.5,l2,0), x4=(0.5,l2/2,l3);
path3 base=x1--x2--x3;
triple b3=planeproject(base,normal(base))*x4;
draw(x4--x1^^x4--x2^^x4--x3,dashed);
draw(b3--x4,red);
draw(x1--x2--x3--cycle);
dot("$x_1$",x1,W);
dot("$x_2$",x2,E);
dot("$x_3$",x3,E);
dot("$x_4$",x4,N);
dot("$B_3$",b3,S,red);