平滑的 pgf 图

平滑的 pgf 图

我试图将函数 $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 fory`。

但或许你不知道r

相关内容