如何使用 Asymptote、Metapost 或任何可以生成高质量图形的工具绘制圆角立方体?圆角立方体例如是明科夫斯基和 C+S 的边界,其中 C=[-1,1]^3,S 是单位球面。使用 Asymptote 是可能的,但我必须参数化并绘制大约 26 个表面才能做到这一点(如果有必要,我会这样做)。我想知道是否有更简单的方法。
我希望能够说出这个圆角立方体的中心在哪里,如果可能的话,能够绘制 aC+rS 之类的东西,其中 a、c 是正实数,即修改球体和立方体的半径。也许这个要求太高了……这实际上是第一种方法的缺陷,即在 Asymptote 中绘制所有需要的参数化表面:如果我想绘制两个具有不同参数 a、r 的立方体,我必须做两次同样的事情。
答案1
我认为,Asymptote 中最简单的方法(需要的代码行数最少且人脑用量最少)是使用contour3
包(不幸的是,没有很好的文档记录)。该函数定义了给定坐标函数的零集表面(x,y,z)
。因此,类似下面的代码(可能略作调整)可以工作:
import graph3;
import contour3;
size(200,0);
currentprojection=orthographic((6,8,2),up=Y);
real abs(real z) { return (z > 0) ? z : 0 - z; }
real trunc(real z, real w) { return ( z > w) ? z - w: 0;}
real abstractroundedcube( real x, real y, real z, real a, real r) {
return trunc(abs(x),a)^2 + trunc(abs(y),a)^2 + trunc(abs(z),a)^2 - r^2;
}
real aroundedcube( real x, real y, real z) {
return abstractroundedcube( x,y,z,2,1);
}
draw( surface( contour3( aroundedcube,(-4,-4,-4),(4,4,4),50)),blue+opacity(0.75),render(merge=true));
我们首先导入graph3
和contour3
。接下来的两行只是任意选择的基本设置。核心在于函数abs
、trunc
和的定义abstractroundedcube
。函数abs
只是绝对值函数,trunc
函数取两个实数值。它返回z-w
如果z > w
和0
否则,换句话说,它w
从中截断第一个单位z
。
对于abstractroundedcube
函数,给定一个坐标(x,y,z)
和两个参数(a,r)
,语句的前半部分return
给出点(x,y,z)
到立方体表面的(平方)距离 $[-a,a]^3$(其中如果点在立方体内,距离设置为 0)。然后我们从中减去r^2
。因此,这个函数恰好消失在圆角立方体 aC + rS 的表面上,正如您所期望的那样。
该aroundedcube
函数只是一个虚拟函数,因为该contour3
函数仅将 3 个实参数的函数作为第一个输入,所以我必须在某处指定参数a = 2
和r = 1
示例。
最后一个调用是绘制立方体。输出如下所示:
不幸的是,渲染过程中会出现一些瑕疵。您可以尝试增加分辨率(调用中的最后一个参数contour3
);这可能还需要您提供asymptote
更多内存来运行。
另一方面,如果您明确定义表面的参数化(而不是通过隐式定义contour3
),那么您可能会获得更高质量的输出。对于圆形球体,即使有 26 个表面,它们也会分解为 12 条边、8 个角和 6 个面。每个都可以相同地完成。角只是半径为 r 的 1/8 球体,边是半径为 r 且长度为 2a 的四分之一圆柱体,而面是立方体 [-a,a]^3 的面向外位移距离 r。在考虑 (a,r) 参数的同时精确地对它们进行参数化应该不会太难。