我正在尝试绘制(绘制)尖峰灾难使用任何软件逻辑将表面放入乳胶中。我完全被难住了,因为我绝对不是数学家。表面具有潜力:
V(x) = F(x,u,v) = x^4 + ux^2 + vx
所以它应该由这个隐式方程给出:
4x^3 + 2ux + v = 0
但我不知道如何实现这一点。显然 gnuplot不能这样做(即使我发现即将发生的事情)所以我应该选择中科院比如 Octave 或者编写一些脚本千里马首先,然后输入 gnuplot 或导出图形。理想情况下,如果事情像这样简单就好了Mathematica 示例:
F[x_, u_, v_] := x^4 + u x^2 + v*x
Needs["Graphics`ContourPlot3D`"]
ContourPlot3D[Evaluate[D[F[x, u, v], x]],
{u, -2.5, 2}, {v, -2.2, 3}, {x, -1.4, 1.3},
PlotPoints -> 7, ViewPoint -> {-1.5, 1.5, 1.4},
Axes -> True, ContourStyle -> {EdgeForm[]},
AxesLabel -> TraditionalForm /@ {u, v, x}] // Timing
编辑/更新
所以我挖了很多,显然,如果没有数学家的能力,我无法完美地做到这一点(这是肯定的),所以我决定坚持使用隐式求解方法。我可以将 Mathematica 代码翻译成智者:
u, v, x = var('u, v, x')
f(u,v,x) = x^4 + u*x^2 + v*x
g = f.diff(x)
implicit_plot3d(g, (u, -2, 2), (v, -2, 2), (x, -2, 2))
它产生了很好的结果:
您还可以查看结果cloud.sagemath(需要订阅)。
但不幸的是,3d 图不能以矢量格式导出,也许有一种方法可以导出原始(x,y,z)点,不知道......我尝试了另一种解决方案,使用psplotImpIIID
ps-tricks 的实验功能,它很丑陋并且产生了很多伪影。
最后pstricks
,可以这样做:
\begin{pspicture}(-6,-4)(6,5)
\pstThreeDCoor[xMin=-4,xMax=4,yMin=-4,yMax=4,zMin=-4,zMax=4,RotY=90,RotX=25]
\psplotThreeD[plotstyle=line,hiddenLine,% does not work in my case (xelatex?)
yPlotpoints=50,xPlotpoints=50,linewidth=.5pt,algebraic](-3,3)(-3,3){4*x^3 - 2*y*x}
\end{pspicture}
优点是我们可以轻松旋转轴,缺点(从 pstricks 新手的角度来看)是造型,而且我需要剪辑结果图像。还有一个解决方案是使用R 包我试过了,效果很好,可以输出矢量图形。但说实话,我想我循环了网络(我甚至用 Blender Python 编写了脚本),而且肯定没有简单直接的解决方案。
答案1
\documentclass[pstricks]{standalone}
\usepackage{pst-solides3d}
\begin{document}
\begin{pspicture}(-4,-6)(5,9)
\psset{viewpoint=100 30 40 rtp2xyz,lightsrc=viewpoint, Decran=120}
\psSurface[ngrid=.15 .15,incolor=yellow,hue=0 1,linewidth=0.1\pslinewidth,
algebraic,axesboxed](-1,-2)(1,2){ 4*x^3 - 2*y*x}
\end{pspicture}
\end{document}
z 最大值/最小值只能在 PostScript 级别处理(将来会改变)
\documentclass[pstricks]{standalone}
\usepackage{pst-solides3d}
\begin{document}
\begin{pspicture}(-4,-6)(5,9)
\psset{viewpoint=100 30 40 rtp2xyz,lightsrc=viewpoint, Decran=120}
\psSurface[ngrid=0.1 0.15,incolor=yellow,hue=0 1,linewidth=0.1\pslinewidth,axesboxed,
% algebraic](-2,-2)(2,2){4*x^3 -2*y*x}
](-2,-2)(1,3){ 4 x 3 exp mul 2 y mul x mul sub
dup 4 gt { pop 4 } if
dup -4 lt { pop -4 } if
}
\end{pspicture}
\end{document}
但是,这些值不会被忽略,它们仅被设置为最大值/最小值。
答案2
您实际上可以通过以下方式做到这一点pgfplots
,但是为了使它更好一些,您必须切换到 LuaLaTeX,因为 PDFLaTeX 会因内存限制而堵塞(由于每个轴有许多样本。您不需要那么多,但为什么不呢:P)。
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.10}
\begin{document}
\begin{tikzpicture}
\begin{axis}[y domain=-4:4,
domain=-2:2,
restrict z to domain=-5:5,
samples=100,
view={43}{8},
mesh/interior colormap name=hot,
colormap/blackwhite,
xlabel=$x$,ylabel=$u$,zlabel=$v$,grid=both
]
\addplot3[surf] {-4*x^3 - 2*y*x};
\end{axis}
\end{tikzpicture}
\end{document}
如果你决定隐藏粗糙的边缘,你可以得到一个低保真版本,LaTeX 也可以处理
\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.10}
\begin{document}
\begin{tikzpicture}
\begin{axis}[y domain=-3:3,
domain=-2:2,zmin=-3,zmax=3,
restrict z to domain=-5:5,
samples=45,
view={48}{15},
mesh/interior colormap name=hot,
colormap/blackwhite,
xlabel=$x$,ylabel=$u$,zlabel=$v$,grid=both
]
\addplot3[surf] {-4*x^3 - 2*y*x};
\end{axis}
\end{tikzpicture}
\end{document}
答案3
我认为你所要求的正是ePiX
的,(http://bay.uchicago.edu/tex-archive/graphics/epix/samples/butterfly.xp)例子。
如果我理解代码的话,策略是将表面分为三个部分。将其转换为pgfplots
和会很有趣asymptote
。asymptote
甚至可以隐式定义这条曲线(它在这方面非常擅长)。
这是结果的图像(我没有制作它):
答案4
Asymptote 可以使用smoothcontour3 模块。该模块已整合到 Asymptote 的(刚刚发布的)2.33 版中,但如果您没有早期版本,则可以使用上面的链接安装该模块。(只需将文件复制到包含图像的目录中即可。)以下是您可能绘制的曲面:
\documentclass{standalone}
\usepackage{asypictureB}
\begin{document}
\begin{asypicture}{name=catastrophe_surface}
settings.outformat = "png";
settings.render = 32;
size(8cm);
import smoothcontour3;
import graph3;
currentprojection=perspective(3*(4,-6,3));
real f(real v, real u, real x) { return 4x^3 + 2u*x + v; }
draw(implicitsurface(f,(-2,-2,-2),(2,2,2), n=15, overlapedges=true),
surfacepen=material(diffusepen=gray,
ambientpen=blue));
zaxis3("$x$", Bounds, InTicks, zmin=-2, zmax=2);
xaxis3("$v$", Bounds, InTicks);
yaxis3("$u$", Bounds, InTicks(beginlabel=false));
\end{asypicture}
\end{document}
如果您将环境中的前两行更改asypicture
为
settings.outformat = "pdf";
settings.render = 0;
但生成的 pdf 文件将会非常大,并且在大多数查看器中看起来都很糟糕(根据我的经验,它在 Adobe Reader 中看起来还可以,但在我尝试过的任何其他浏览器中都不行)。
无论如何,对于这个特定问题,我认为你最好使用一点数学知识
4x^3 + 2ux + v = 0
v = -4x^3 - 2ux
将其转换为函数图,而不是隐式定义的曲面。隐式定义的曲面通常看起来不太好看。
这是使用 Asymptote 的非隐式版本。(请注意,它需要我的crop3D 模块。
settings.outformat = "png";
settings.render = 16;
size(8cm);
import graph3;
import crop3D;
currentprojection=perspective(3*(4,-6,3));
triple F(pair ux) {
real u = ux.x;
real x = ux.y;
return (-4x^3 - 2*u*x, u, x);
}
surface s = surface(F, (-2,-2), (2,2), nu=20, usplinetype=Spline);
draw(crop(s,(-2,-2,-2),(2,2,2)), surfacepen=material(diffusepen=gray, ambientpen=blue));
zaxis3("$x$", Bounds, InTicks, zmin=-2, zmax=2);
xaxis3("$v$", Bounds, InTicks);
yaxis3("$u$", Bounds, InTicks(beginlabel=false));
它比隐式版本编译得更快,并且在我看来,给出了更好的结果: