TiKz 中的极三角形

TiKz 中的极三角形

我正在尝试绘制一个球面三角形 $ABC$ 及其极坐标对应点 $A'B'C'$,如图所示

在此处输入图片描述

使用 TiKz 可以实现吗?在TikZ - 球面三角形但没有答案。

答案1

这是一个可行的方法。它有很多计算,但它们很简单(我希望)并且相当重复。

\documentclass {standalone}
\usepackage    {tikz}
\usetikzlibrary{3d}
\usetikzlibrary{calc}
\usetikzlibrary{math}

% isometric axes
\pgfmathsetmacro\xx{1/sqrt(2)}
\pgfmathsetmacro\xy{1/sqrt(6)}
\pgfmathsetmacro\zy{sqrt(2/3)}

% some functions (cross products)
\tikzmath%
{%
  function crossx(\mx,\my,\mz,\nx,\ny,\nz)
  {% cross product, x coordinate, normailized
    \pxx = \my*\nz-\mz*\ny;
    \pyy = \mz*\nx-\mx*\nz;
    \pzz = \mx*\ny-\my*\nx;
    return {\pxx/sqrt(\pxx*\pxx+\pyy*\pyy+\pzz*\pzz)};
  };
  function crossy(\mx,\my,\mz,\nx,\ny,\nz)
  {% cross product, y coordinate, normailized
    \pxx = \my*\nz-\mz*\ny;
    \pyy = \mz*\nx-\mx*\nz;
    \pzz = \mx*\ny-\my*\nx;
    return {\pyy/sqrt(\pxx*\pxx+\pyy*\pyy+\pzz*\pzz)};
  };
  function crossz(\mx,\my,\mz,\nx,\ny,\nz)
  {% cross product, z coordinate, normailized
    \pxx = \my*\nz-\mz*\ny;
    \pyy = \mz*\nx-\mx*\nz;
    \pzz = \mx*\ny-\my*\nx;
    return {\pzz/sqrt(\pxx*\pxx+\pyy*\pyy+\pzz*\pzz)};
  };
}

\newcommand{\greatcircle}[6] % pole x, y, z, color, two orientation factors (+1/-1)
{%
  \coordinate (P)  at (#1,#2,#3);                  % pole
  \coordinate (N)  at ($(0,0,0)!#6*1.25cm!(P)$);   % these points are
  \coordinate (S)  at ($-1*(N)$);                  % used to clip the
  \coordinate (E)  at ($(0,0,0)!-1.25cm!270:(P)$); % ellipses
  \coordinate (W)  at ($-1*(E)$);                  % ...
  \coordinate (NW) at ($(N)+(W)$);
  \coordinate (NE) at ($(N)+(E)$);
  \coordinate (SW) at ($(S)+(W)$);
  \coordinate (SE) at ($(S)+(E)$);
  \pgfmathsetmacro\ptheta{atan(#2/#1)} % pole, spherical coordinate theta
  \pgfmathsetmacro\pphi  {#5*acos(#3)} % pole, spherical coordinate phi
  \begin{scope}
    \clip (W) -- (SW) -- (SE) -- (E) -- cycle;
    \draw[rotate around z=\ptheta,rotate around y=\pphi,%
          canvas is xy plane at z=0,#4] (0,0) circle (1);
  \end{scope}
  \begin{scope}
    \clip (W) -- (NW) -- (NE) -- (E) -- cycle;
    \draw[rotate around z=\ptheta,rotate around y=\pphi,%
          canvas is xy plane at z=0,#4,densely dotted] (0,0) circle (1);
  \end{scope}
}

\begin{document}
\begin{tikzpicture}[line cap=round,line join=round,scale=2,%
                    x={({-\xx cm,-\xy cm})},y={(\xx cm,-\xy cm)},z={(0 cm,\zy cm)}]
% points A, B, C in spherical coordinates
\def\atheta{55}
\def\aphi  {30}
\def\btheta{10}
\def\bphi  {85}
\def\ctheta{70}
\def\cphi  {80}
% points A, B, C in cartesian coordinates
\pgfmathsetmacro\ax{cos(\atheta)*sin(\aphi)}
\pgfmathsetmacro\ay{sin(\atheta)*sin(\aphi)}
\pgfmathsetmacro\az{cos(\aphi)});
\pgfmathsetmacro\bx{cos(\btheta)*sin(\bphi)}
\pgfmathsetmacro\by{sin(\btheta)*sin(\bphi)}
\pgfmathsetmacro\bz{cos(\bphi)});
\pgfmathsetmacro\cx{cos(\ctheta)*sin(\cphi)}
\pgfmathsetmacro\cy{sin(\ctheta)*sin(\cphi)}
\pgfmathsetmacro\cz{cos(\cphi)});
% polar points P, Q, R in cartesian coordinates
\pgfmathsetmacro\px{crossx(\ax,\ay,\az,\bx,\by,\bz)}
\pgfmathsetmacro\py{crossy(\ax,\ay,\az,\bx,\by,\bz)}
\pgfmathsetmacro\pz{crossz(\ax,\ay,\az,\bx,\by,\bz)}
\pgfmathsetmacro\qx{crossx(\cx,\cy,\cz,\ax,\ay,\az)}
\pgfmathsetmacro\qy{crossy(\cx,\cy,\cz,\ax,\ay,\az)}
\pgfmathsetmacro\qz{crossz(\cx,\cy,\cz,\ax,\ay,\az)}
\pgfmathsetmacro\rx{crossx(\bx,\by,\bz,\cx,\cy,\cz)}
\pgfmathsetmacro\ry{crossy(\bx,\by,\bz,\cx,\cy,\cz)}
\pgfmathsetmacro\rz{crossz(\bx,\by,\bz,\cx,\cy,\cz)}
% triangles
\greatcircle{\ax}{\ay}{\az}{red} { 1}{1}
\greatcircle{\bx}{\by}{\bz}{red} { 1}{1}
\greatcircle{\cx}{\cy}{\cz}{red} { 1}{1}
\greatcircle{\px}{\py}{\pz}{blue}{-1}{1}
\greatcircle{\qx}{\qy}{\qz}{blue}{ 1}{1}
\greatcircle{\rx}{\ry}{\rz}{blue}{-1}{1}
% sphere and axes
\draw (0,0,0) circle (1 cm);
\draw[gray,dashed] (0,0,0) -- (1,0,0);
\draw[gray,dashed] (0,0,0) -- (0,1,0);
\draw[gray,dashed] (0,0,0) -- (0,0,1);
\draw[gray,-latex] (1,0,0) -- (1.5,0,0) node (X) [left]  {$x$};
\draw[gray,-latex] (0,1,0) -- (0,1.5,0) node (Y) [right] {$y$};
\draw[gray,-latex] (0,0,1) -- (0,0,1.5) node (Z) [above] {$z$};
% points
\fill[blue] (\ax,\ay,\az) circle (0.5pt) node [above]       {$A$};
\fill[blue] (\bx,\by,\bz) circle (0.5pt) node [below]       {$B$};
\fill[blue] (\cx,\cy,\cz) circle (0.5pt) node [below left]  {$C$};
\fill[red]  (\px,\py,\pz) circle (0.5pt) node [below right] {$C'$};
\fill[red]  (\qx,\qy,\qz) circle (0.5pt) node [left]        {$B'$};
\fill[red]  (\rx,\ry,\rz) circle (0.5pt) node [above left]  {$A'$};
\fill[gray] (0,0,0)       circle (0.5pt) node [left]        {$O$};
\end{tikzpicture}
\end{document}

在此处输入图片描述

一点解释。首先,为简单起见,我使用单位球体,数据点以球面坐标提供。然后这里的关键是极点。给定球体上的两个点,我们寻找通过它们的大圆,以及如果所述圆周是赤道的话将是北极的点。设A(ax,ay,az)B(bx,by,bz)为点,然后我们可以计算叉积(抱歉,没有 MathJax):

            | i  j  k  |
v = A x B = | ax ay az |
            | bx by bz |

上述向量v将为我们提供找到北极的方向,如果我们对其进行归一化(除以其模数),新向量u将准确指向极点(C'在我的绘图中)。但这还不是全部,因为这个u球坐标中的向量将为 tikz 3d 中包含赤道(穿过A和的大圆B)的新画布提供角度。由于透视,我们将圆视为椭圆,其半长轴垂直于的投影u,因此再次,可以使用向量来裁剪椭圆并分离可见部分和不可见部分。

相关内容