我的论文有一个问题,这个问题很容易用“手工”绘图来展示,但在 tikz/pgfplot 中绘制草图却相当困难(我使用这些软件包的原因主要是因为我的论文是用 latex 写的,所以在 latex 文件中绘制这幅图并编译所有内容会很棒)。我的 tikz/pgfplots 技能不是很好,因为我才刚开始使用它们。
问题如下:我有一个向量J在由三个坐标轴系统(例如 x、y、z)定义的 3D 空间中。向量从系统的原点开始,具有任意长度和方向。在 3D 空间中,此向量可以定义一个球体,其半径 R 恰好由向量的长度给出。如果绕 z 轴旋转向量,向量的箭头将定义纬度的平行线(图中的虚线圆圈)。现在,如果我们将 K 表示为向量的投影J在 z 轴上,点 A 是虚线圆心,我们现在可以让 A 围绕 z 轴“上”和“下”的稳定位置振荡。如果 A 上下振荡,同时我们也旋转J围绕 z 轴,箭头的轨迹将定义一条余弦曲线(照片中的红色曲线)
问题我如何使用 tikz/pgfplots 在 latex 中绘制这个?
从数学上讲,这很容易描述,因为球体、虚线圆和红色曲线可以在球面坐标中参数化。到目前为止,我只画了球体,这就是我所知道的。我想我必须再添加两个图,一个用于虚线圆,一个用于红色振荡平行纬线。
\begin{figure}
\centering
\caption{The wobbling motion viewed in a 3D space generated by the three components of the total angular momentum $\mathbf{J}$.}
\begin{tikzpicture}
\begin{axis}[%
axis equal,
width=15cm,
height=15cm,
axis lines = center,
xlabel = {$x$},
ylabel = {$y$},
zlabel = {$z$},
ticks=none,
enlargelimits=0.3,
view/h=45,
scale uniformly strategy=units only,
]
\addplot3[%
opacity = 0.2,
surf,
z buffer = sort,
samples = 20,
variable = \u,
variable y = \v,
domain = 0:180,
y domain = 0:360,
]
({cos(u)*sin(v)}, {sin(u)*sin(v)}, {cos(v)});
\end{axis}
\end{tikzpicture}
\end{figure}
任何帮助都将不胜感激。很抱歉问题这么长,但我无法用更简短的方式来表述这个问题。
答案1
以下是基于的提议Alain Matthes 宏(略作调整)。
\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{calc,fadings,decorations.pathreplacing,shadings,angles,quotes,
intersections}
\tikzset{hidden lines/.style={opacity=0.4}}
\pgfkeys{/tikz/.cd,
visible angle A/.store in=\VisibleAngleA,
visible angle A=0,
visible angle B/.store in=\VisibleAngleB,
visible angle B=0,
}
\newcommand\pgfmathsinandcos[3]{%
\pgfmathsetmacro#1{sin(#3)}%
\pgfmathsetmacro#2{cos(#3)}%
}
\newcommand\LongitudePlane[3][current plane]{%
\pgfmathsinandcos\sinEl\cosEl{#2} % elevation
\pgfmathsinandcos\sint\cost{#3} % azimuth
\tikzset{#1/.style={cm={\cost,\sint*\sinEl,0,\cosEl,(0,0)}}}
}
\newcommand\LatitudePlane[3][current plane]{%
\pgfmathsinandcos\sinEl\cosEl{#2} % elevation
\pgfmathsinandcos\sint\cost{#3} % latitude
\pgfmathsetmacro\yshift{\RadiusSphere*\cosEl*\sint}
% \tikzset{#1/.style={cm={\cost,0,0,\cost*\sinEl,(0,\yshift)}}} %
\tikzset{#1/.style={x={(\cost,0)},y={(0,\cost*\sinEl)},z={(0,1)},yshift={\yshift*1cm}}} %
}
\newcommand\NewLatitudePlane[4][current plane]{%
\pgfmathsinandcos\sinEl\cosEl{#3} % elevation
\pgfmathsinandcos\sint\cost{#4} % latitude
\pgfmathsetmacro\yshift{#2*\cosEl*\sint}
\tikzset{#1/.style={cm={\cost,0,0,\cost*\sinEl,(0,\yshift)}}} %
}
\newcommand\DrawLongitudeCircle[2][1]{
\LongitudePlane{\angEl}{#2}
\tikzset{current plane/.prefix style={scale=#1}}
% angle of "visibility"
\pgfmathsetmacro\angVis{atan(sin(#2)*cos(\angEl)/sin(\angEl))} %
\draw[current plane] (\angVis:1) arc (\angVis:\angVis+180:1);
\draw[current plane,hidden lines] (\angVis-180:1) arc (\angVis-180:\angVis:1);
}
\newcommand\DrawLongitudeArc[4][black]{
\LongitudePlane{\angEl}{#2}
\tikzset{current plane/.prefix style={scale=1}}
\pgfmathsetmacro\angVis{atan(sin(#2)*cos(\angEl)/sin(\angEl))} %
\pgfmathsetmacro\angA{mod(max(\angVis,#3),360)} %
\pgfmathsetmacro\angB{mod(min(\angVis+180,#4),360} %
\draw[current plane,#1,hidden lines] (#3:\RadiusSphere) arc (#3:#4:\RadiusSphere);
\draw[current plane,#1] (\angA:\RadiusSphere) arc (\angA:\angB:\RadiusSphere);
}%
\newcommand\DrawLatitudeCircle[2][1]{
\LatitudePlane{\angEl}{#2}
\tikzset{current plane/.prefix style={scale=#1}}
\pgfmathsetmacro\sinVis{sin(#2)/cos(#2)*sin(\angEl)/cos(\angEl)}
% angle of "visibility"
\pgfmathsetmacro\angVis{asin(min(1,max(\sinVis,-1)))}
\draw[current plane] (\angVis:1) arc (\angVis:-\angVis-180:1);
\draw[current plane,hidden lines] (180-\angVis:1) arc (180-\angVis:\angVis:1);
}
\newcommand\DrawLatitudeArc[4][black]{
\LatitudePlane{\angEl}{#2}
\tikzset{current plane/.prefix style={scale=1}}
\pgfmathsetmacro\sinVis{sin(#2)/cos(#2)*sin(\angEl)/cos(\angEl)}
% angle of "visibility"
\pgfmathsetmacro\angVis{asin(min(1,max(\sinVis,-1)))}
\pgfmathsetmacro\angA{max(min(\angVis,#3),-\angVis-180)} %
\pgfmathsetmacro\angB{min(\angVis,#4)} %
\tikzset{visible angle A=\angA,visible angle B=\angB}
\draw[current plane,#1,hidden lines] (#3:\RadiusSphere) arc (#3:#4:\RadiusSphere);
\draw[current plane,#1] (\angA:\RadiusSphere) arc (\angA:\angB:\RadiusSphere);
}
%% document-wide tikz options and styles
\tikzset{%
>=latex, % option for nice arrows
inner sep=0pt,%
outer sep=2pt,%
mark coordinate/.style={inner sep=0pt,outer sep=0pt,minimum size=3pt,
fill=black,circle}%
}
\begin{document}
\begin{tikzpicture} %
\def\RadiusSphere{3} % sphere radius
\def\angEl{20} % elevation angle
\draw[->] (0,0,0) -- ({1.2*\RadiusSphere},0,0) coordinate(Y) node[below] {$y$};
\draw[->] (0,0,0) -- (0,{1.2*\RadiusSphere},0) coordinate(Z) node[left] {$z$};
\draw[->] (0,0,0) -- (0,0,{2.2*\RadiusSphere}) coordinate(X) node[below] {$x$};
\shade[ball color = gray!40, opacity = 0.5,name path=circle] (0,0) circle (\RadiusSphere);
\DrawLatitudeArc[blue]{0}{-200}{160}
\DrawLatitudeArc[blue]{50}{-200}{160}
\typeout{\VisibleAngleA,\VisibleAngleB}
\LatitudePlane[my plane]{\angEl}{50}
\draw[my plane,red,samples=100] plot[variable=\x,domain=\VisibleAngleA:\VisibleAngleB]
({3*cos(\x)},{3*sin(\x)},{-0.6*cos(15*\x)}) coordinate (P);
\draw[my plane,red,samples=100,opacity=0.4] plot[variable=\x,domain=\VisibleAngleB:{\VisibleAngleA+360}]
({3*cos(\x)},{3*sin(\x)},{-0.6*cos(15*\x)});
\draw[->](0,0,0) coordinate(O) -- (P);
\draw (Z) -- (O) -- (P)
pic [draw=green!50!black, fill=green!20, angle radius=9mm,
"$\theta$"] {angle = P--O--Z};
\path (O) |- (P) coordinate[pos=0.5] (Q);
\fill (Q) circle (1pt);
\draw[decorate,decoration={brace,raise=1pt}] (O) -- (Q) node[midway,left] {$K$};
\end{tikzpicture}
\end{document}
不幸的是,红色曲线的某些非隐藏部分被绘制为隐藏(因为曲线的底部被隐藏了)。