答案1
首先,渲染引擎中没有“分层”机制;参见此功能请求。因此,如果您想模拟一个(例如,使不透明物体后面的路径可见),您有两个选择:
- 通过设置 放弃隐藏对象移除。除非您使用类似模块,
settings.render = 0;
否则这对您的事业没有帮助surfacepaths
这个答案或者这个答案实际计算对象前后路径的部分。(此模块不完整,可能适用于您的实际用例,也可能不适用。它还将隐藏的路径绘制为褪色,我发现这通常看起来比虚线更好。也许以后我会看看是否可以在这个答案中添加一些内容,显示允许使用虚线路径的修改版本。) - 通过将一些物体移近(或远离)相机来模拟分层。这通常是首选解决方案,但对于透视投影来说,它比正交投影更难实现。
Paolo 的解决方案是 2 的一个巧妙变体,基于这样的观察:在实线曲线上绘制的虚线看起来与实线曲线完全一样。数学估算是不必要的;对于正交投影,正是将对象向相机shift(n * unit(currentprojection.camera))
移动单位所需的变换。做得太大不太可能成为问题,因此您可以使用类似的方法(或从开始并将其加倍,直到图片看起来正确)。n
n
n=1000
n=1
处理透视投影不可避免地是一个问题——尤其是因为靠近相机的线条实际上会显得更粗。这是我目前能做的最好的事情:
import graph3;
size(6cm,0);
settings.render = 4;
currentprojection=perspective(5*(4, 1, 1), showtarget=true, autoadjust=false, center=true);
// UTILITY FUNCTIONS
triple cameradirection(triple pt, projection P=currentprojection) {
if (P.infinity) {
return unit(P.camera);
} else {
return unit(P.camera - pt);
}
}
triple towardcamera(triple pt, real distance=1, projection P=currentprojection) {
return pt + distance * cameradirection(pt, P);
}
path3 towardcamera(path3 g, real distance=1, projection P=currentprojection) {
triple f(real t) {
return towardcamera(point(g,t), distance, P);
}
return graph(f, 0, length(g), operator..);
}
pen shortdashed = linetype(new real[] {4, 4});
// SURFACE
triple S(pair uv) {
real x = cos(uv.x)*sin(uv.y);
real y = sin(uv.x)*sin(uv.y);
real z = cos(uv.y);
return (x-(1-z**2-y**2), y-0.3*sin(z*pi), z);
}
// BOUNDARY
triple dS(real u) {
return S((u, pi/2));
}
// GRAPHICAL ELEMENTS
surface s = surface(S, (0, 0), (2pi, pi/2), 64, 64, Spline);
path3 ds = graph(dS, 0, 2pi);
draw(s, surfacepen=material(diffusepen=gray(0.6),
emissivepen=gray(0.3),
specularpen=gray(0.1)));
// Draw boundary.
draw(ds);
// Draw dashed version of boundary out in front. As long as it's exactly the
// same color and width as the solid path, the dashing pattern will only show up
// when the solid path isn't behind it.
//draw(shift(4*unit(currentprojection.camera))*ds, dashed);
draw(towardcamera(ds, 4), linetype(new real[] {4, 4}));
它在几个方面并不理想。首先,图片边缘有多余的空白。(这可以通过删除参数来解决autoadjust=false
,但这也会弄乱虚线路径。)其次,虚线离相机更近,比实线更粗。这可以通过将相机移远来缓解——但如果你要这样做,你基本上只是试图让透视投影表现得像正交投影;为什么不一开始就使用正交投影呢?