虽然PGFplots
它是许多描绘的完美工具,但不幸的是,它无法正确处理z buffer
相交表面(目前,2015 年 10 月 9 日)。我试图通过绘图并将绘图放在轴环境中来克服这个问题gnuplot
。set terminal tikz
但PGFplots
我似乎无法管理后者。
从http://gnuplot.sourceforge.net/demo_5.0/surface2.9.gnu作为示例,我将终端更改为tikz
:
set terminal tikz standalone
set output 'main.tex'
set dummy u, v
set key bmargin center horizontal Right noreverse enhanced autotitle nobox
set parametric
set view 50, 30, 1, 1
set isosamples 50, 20
set hidden3d back offset 1 trianglepattern 3 undefined 1 altdiagonal bentover
set style data lines
set ticslevel 0
set title "Interlocking Tori"
set urange [ -3.14159 : 3.14159 ] noreverse nowriteback
set vrange [ -3.14159 : 3.14159 ] noreverse nowriteback
splot cos(u)+.5*cos(u)*cos(v),sin(u)+.5*sin(u)*cos(v),.5*sin(v) with lines, 1+cos(u)+.5*cos(u)*cos(v),.5*sin(v),sin(u)+.5*sin(u)*cos(v) with lines
生成的 tex 文件main.tex
包含以下内容
\documentclass[10pt]{article}
\usepackage[T1]{fontenc}
\usepackage{textcomp}
\usepackage[utf8x]{inputenc}
\usepackage{gnuplot-lua-tikz}
\pagestyle{empty}
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{\gpbboxborder}
\begin{document}
\begin{tikzpicture}[gnuplot]
%% generated with GNUPLOT 4.6p5 (Lua 5.1; terminal rev. 99, script rev. 100)
%% Thu 10 Sep 2015 01:40:19 PM CEST
\path (0.000,0.000) rectangle (12.500,8.750);
\gpcolor{color=gp lt color border}
\node[gp node center] at (6.250,8.163) {Interlocking Tori};
\gpcolor{color=gp lt color 0}
\gpsetlinetype{gp lt plot 0}
\gpsetlinewidth{1.00}
\draw[gp path] (6.400,6.200)--(6.110,6.207);
(...A lot of \draw[gp path] commands...)
%% coordinates of the plot area
\gpdefrectangularnode{gp plot 1}{\pgfpoint{1.800cm}{1.387cm}}{\pgfpoint{10.700cm}{7.979cm}}
\end{tikzpicture}
%% gnuplot variables
\end{document}
从中可以清楚地看出,没有使用PGFplots
轴环境。
编译后lualatex -shell-escape main.tex
得到,这“解决”了z buffer
问题。但是如何在良好的PGFplots
轴环境中获得这些绘图呢?
答案1
在@Christian Feuersänger 引入任何好的界面之前,我们可以仔细地参数化表面并利用现有的排序算法。
\documentclass[border=9,tikz]{standalone}
\usepackage{pgfplots}\pgfplotsset{compat=newest}
\begin{document}
\pgfmathdeclarefunction{X}{0}{%
\pgfmathparse{
y<121?
cos(x)*(3+cos(3*y))
:
(y<139?
inf
:
3+cos(x)*(3+cos(3*y))
)
}%
}
\pgfmathdeclarefunction{Y}{0}{%
\pgfmathparse{
y<121?
sin(x)*(3+cos(3*y))
:
(y<139?
inf
:
sin(3*y)
)
}%
}
\pgfmathdeclarefunction{Z}{0}{%
\pgfmathparse{
y<121?
sin(3*y)
:
(y<139?
inf
:
sin(x)*(3+cos(3*y))
)
}%
}
\tikz[cap=round,join=round]{
\begin{axis}[axis equal]
\addplot3[surf,unbounded coords=jump,
domain =0:360,samples =27,
domain y=0:260,samples y=27,
z buffer=sort,point meta=x]
(X,Y,Z);
\end{axis}
}
\end{document}
更加小心
\documentclass[border=9,tikz]{standalone}
\usepackage{pgfplots}\pgfplotsset{compat=newest}
\begin{document}
\pgfmathdeclarefunction{X}{0}{%
\pgfmathparse{
y<121?
cos(x)*(3+cos(3*y))
:
(y<139?
inf
:
(y<261?
4+cos(x)*(3+cos(3*y))
:
(y<279?
inf
:
8+cos(x)*(3+cos(3*y))
)
)
)
}%
}
\pgfmathdeclarefunction{Y}{0}{%
\pgfmathparse{
y<121?
sin(x)*(3+cos(3*y))
:
(y<139?
inf
:
(y<261?
sin(3*y)
:
(y<279?
inf
:
sin(x)*(3+cos(3*y))
)
)
)
}%
}
\pgfmathdeclarefunction{Z}{0}{%
\pgfmathparse{
y<121?
sin(3*y)
:
(y<139?
inf
:
(y<261?
sin(x)*(3+cos(3*y))
:
(y<279?
inf
:
sin(3*y)
)
)
)
}%
}
\tikz[cap=round,join=round]{
\begin{axis}[axis equal]
\addplot3[surf,unbounded coords=jump,
domain =0:360,samples =27,
domain y=0:400,samples y=41,
z buffer=sort,point meta=x]
(X,Y,Z);
\end{axis}
}
\end{document}
编辑
类似的技巧也用于
所以基本上设置
domain =0:360,samples =36,
domain y=0:260,samples y=27,
将设置域名
和设置
domain =0:360,samples =36,
domain y=0:400,samples y=41,
将设置域名
通过给出unbounded coords=jump
,pgfplots 将删除映射到无穷大的坐标,并且切割表面分成两块。当然,在三次游览的情况下,pgfplots 会将表面分成三块。