我试图将函数 $f(x,y) = -\log(x)-\log(y)$ 绘制为 的曲面pgfplots
。为了获得平滑的水平曲线,我使用了 的面片图patch type=biquadratic
。
\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.7}
\usepgfplotslibrary{patchplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}[xmin=0, xmax=1, ymin=0, ymax=1.4, zmin=0, zmax=6,
axis y line=center, axis x line=center, axis z line=center,
view/h=70, xtick=\empty, ytick=\empty, ztick=\empty,
clip=false, axis on top=false]
\node at (rel axis cs:1,0,0) [above, anchor=north west] {$x_1$};
\node at (rel axis cs:0,1,0) [above, anchor=west] {$x_2$};
\node at (rel axis cs:0,0,1) [above, anchor=south] {$f(x_1,x_2)$};
\addplot3 [patch,patch type=biquadratic,shader=flat,draw=black, draw opacity=0.15,z buffer=sort]
coordinates {
(0.02722593,0.15708631,5.45454545) (0.15708631,0.02722593,5.45454545) (0.14800676,0.01674756,6.00000000) (0.01674756,0.14800676,6.00000000) (0.06539740,0.06539740,5.45454545) (0.15204995,0.02141365,5.72727273) (0.04978707,0.04978707,6.00000000) (0.02141365,0.15204995,5.72727273) (0.05706089,0.05706089,5.72727273)
};
\end{axis}
\end{tikzpicture}
\end{document}
为了清晰起见,我省略了无数生成的数据点,以及最明显的“有问题”补丁。数据由手册第 5.6.1 节中描述的 9 元组组成pgfplots
。
我编写的代码产生了下面的图片(惊人的美丽 - Feuersänger先生:你太棒了!):
这就是我想要的,除了:一些补丁的背面左上角(红色)部分缺失。该怎么办?这是一个错误吗pgfplots
?或者有没有简单的方法可以解决这个问题?
我不太在意特定类型的阴影,但我希望有清晰的格子线。
对于任何感兴趣的人,下面是我生成数据的 Python 代码:
from numpy import linspace, pi, sin, cos, log
from scipy.optimize import bisect
# Code to generate patches
# (x(r,theta), y(r,theta), z(r,theta)), where
# x(r,theta) = 1 - r cos(theta),
# y(r,theta) = 1 - r sin(theta),
# z(r,theta) = -log(x(r,theta)) - log(y(r,theta)).
PATCH = [(0,0), (2,0), (2,2), (0,2), (1,0), (2,1), (1,2), (0,1), (1,1)]
N = 21
zmax = 6
zmin = -log(1)-log(1)
# Determine the value such that z = -log(x(r,theta)) - log(y(r,theta)).
def zinv(theta, z):
f = lambda r: -log(1 - r*cos(theta)) - log(1 - r*sin(theta)) - z
maxr = min(1/cos(theta), 1/sin(theta)) - 1e-6
return bisect(f, 0, maxr)
P = dict()
# Generate lattice points
for i, theta in enumerate(linspace(1e-6, pi/2-1e-6, N)):
for j, z in enumerate(linspace(zmin, zmax, N)):
r = zinv(theta, z)
x = 1 - r * cos(theta)
y = 1 - r * sin(theta)
z = - log(x) - log(y)
P[i,j] = (x,y,z)
# Output patches
for j in range(0, N-1, 2):
for i in range(0, N-1, 2):
for (di, dj) in PATCH:
print "(%0.8f,%0.8f,%0.8f)" % P[i+di,j+dj],
print
答案1
杰克的评论是正确的:问题是由于基于形状的填充仅适用于插值阴影(否则很难实现)而引起的。
您的观察是正确的,faceted interp
就 pdf 大小和渲染时间而言,它效率非常低。不幸的是,我不知道如何改进的系统解决方案faceted interp
。
我担心你必须在更高的采样密度faceted
(这意味着你的格子不如你的屏幕截图中那么好看)或对计算能力/pdf 大小的更高要求之间做出选择faceted interp
。
关于插值阴影本身:我对印刷阴影有相当丰富的经验(至少对于shader=interp
)。
PS 谢谢您的赞扬。
请注意,pgfplots 的最新版本带有新功能patch type sampling
,允许 pgfplots 对您的补丁进行采样。
r
如果你知道和的范围theta
而不需要求解非线性方程,那么你可以使用类似
\addplot3 [patch,
patch type sampling,
variable=\r,
variable y=\t,
% domain=?
domain y=1e-6:pi/2-1e-6,
patch type=biquadratic,shader=flat,draw=black, draw opacity=0.15,z buffer=sort]
({1- r*cos(deg(t))},
{1- r*sin(deg(t))},
{-ln(x)-ln(y)});
或类似的东西。在这种情况下,x
是 *resulting x coordinate, same for
y`。
但或许你不知道r
。