如何在 3D 空间中绘制矢量

如何在 3D 空间中绘制矢量

我的论文有一个问题,这个问题很容易用“手工”绘图来展示,但在 tikz/pgfplot 中绘制草图却相当困难(我使用这些软件包的原因主要是因为我的论文是用 latex 写的,所以在 latex 文件中绘制这幅图并编译所有内容会很棒)。我的 tikz/pgfplots 技能不是很好,因为我才刚开始使用它们。

问题如下:我有一个向量J在由三个坐标轴系统(例如 x、y、z)定义的 3D 空间中。向量从系统的原点开始,具有任意长度和方向。在 3D 空间中,此向量可以定义一个球体,其半径 R 恰好由向量的长度给出。如果绕 z 轴旋转向量,向量的箭头将定义纬度的平行线(图中的虚线圆圈)。现在,如果我们将 K 表示为向量的投影J在 z 轴上,点 A 是虚线圆心,我们现在可以让 A 围绕 z 轴“上”和“下”的稳定位置振荡。如果 A 上下振荡,同时我们也旋转J围绕 z 轴,箭头的轨迹将定义一条余弦曲线(照片中的红色曲线)

三维空间中的矢量 J,K 围绕稳定位置振荡

问题我如何使用 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}

在此处输入图片描述

不幸的是,红色曲线的某些非隐藏部分被绘制为隐藏(因为曲线的底部被隐藏了)。

相关内容