Asymptote 的错误

Asymptote 的错误

我正在尝试使用以下代码绘制一个简单的四面体(渐近线

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 输出,仅 Adob​​e Reader 支持。此外,3D 图片可通过 Adob​​e 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返回的是nO

transform3 planeproject(triple n, triple O=O, triple dir=n);

可以使用normal(path3 p)来找到平面三维路径的单位法向量p。在平面路径定义的平面transform3方向上投影的A由以下公式返回dirp

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

相关内容