绘制尖点突变曲面

绘制尖点突变曲面

我正在尝试绘制(绘制)尖峰灾难使用任何软件逻辑将表面放入乳胶中。我完全被难住了,因为我绝对不是数学家。表面具有潜力:

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))

它产生了很好的结果: Sage 的尖角表面

您还可以查看结果cloud.sagemath(需要订阅)。

但不幸的是,3d 图不能以矢量格式导出,也许有一种方法可以导出原始(x,y,z)点,不知道......我尝试了另一种解决方案,使用psplotImpIIIDps-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}

pst-plot3d 尖点表面

优点是我们可以轻松旋转轴,缺点(从 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和会很有趣asymptoteasymptote甚至可以隐式定义这条曲线(它在这方面非常擅长)。

这是结果的图像(我没有制作它):

蝴蝶

答案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 文件将会非常大,并且在大多数查看器中看起来都很糟糕(根据我的经验,它在 Adob​​e 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));

它比隐式版本编译得更快,并且在我看来,给出了更好的结果:

在此处输入图片描述

相关内容