在 TiKz 中从球体上切下一些片段

在 TiKz 中从球体上切下一些片段

我正在尝试做类似的事情图片。我使用了以下例子问题开始。这是我的代码

\documentclass[11pt]{standalone}
\usepackage{tikz,amsmath}
\usepackage{tikz-3dplot}
\usetikzlibrary{shapes,positioning}
\usetikzlibrary{calc,fadings,decorations.pathreplacing,backgrounds}
\usepackage{pgfplots}

\begin{document}
%% helper macros

\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{\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);
 }

\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);
 }
\newcommand\DrawLatitudeCircleHalf[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)))}
  \filldraw[current plane] (0,0,0)--(\angVis-45:1) arc (\angVis-45:\angVis-110:1) -- (0,0,0)
 }
\newcommand\LongitudePlaneHalf[2][current plane]{%
  \pgfmathsinandcos\sinEl\cosEl{\angEl} % elevation
  \pgfmathsinandcos\sint\cost{#2} % azimuth
  \tikzset{#1/.estyle={cm={\cost,\sint*\sinEl,0,\cosEl,(0,0)}}}
}
\newcommand\DrawLongitudeCircleHalf[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+127:1);
 }

%% 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{tikzpicture}%[tdplot_main_coords] % "THE GLOBE" showcase

 \def\R{2.5} % sphere radius
 \def\angEl{35} % elevation angle
 \def\angleLongitudeP{-110} % longitude of point P
  \def\angleLongitudeQ{-45} % longitude of point Q
  \def\angleLatitudeQ{30} % latitude  Q    ; 0 latitude of P 
  \def\angleLongitudeA{-20} % longitude of point A

  \LongitudePlaneHalf[PLongitudePlane]{\angleLongitudeP}
  \LongitudePlaneHalf[QLongitudePlane]{\angleLongitudeQ}
  \LongitudePlaneHalf[ALongitudePlane]{\angleLongitudeA}  
 \draw[] (0,0) circle (\R);
 \foreach \t in {-80,-60,...,80} { \DrawLatitudeCircle[\R]{\t} }
 \foreach \t in {-5,-35,...,-175} { \DrawLongitudeCircle[\R]{\t} }


% \begin{pgfonlayer}{background}  
%   \node {\includegraphics[scale=0.0708]{images/Earth.png}};  
% \end{pgfonlayer}
 \pgfmathsetmacro\H{\R*cos(\angEl)} % distance to north pole


 %%%%%%%%%%%%%%%
 \coordinate[] (O) at (0,0,0);
 \coordinate[] (N) at (0,\H);
  \coordinate[] (S) at (0,-\H);
   \path[PLongitudePlane] (0:\R) coordinate (P);
   \path[QLongitudePlane] (0:\R) coordinate (B);
\color{blue!20!white};
\DrawLatitudeCircleHalf[\R]{0};

\color{red};
\DrawLongitudeCircleHalf[\R]{70};


        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    \end{tikzpicture}
    \end{document} 

在我的结果中,红线越过了“北极”。我需要用颜色填充该部分,但甚至无法画出边界。

我的结果

答案1

你使用的宏有些过时了,而且只加载了 ,没有使用tikz-3dplot。有一些高级但非官方的工具可以实现这一点,比如这个。我保留了生成网格的代码中的线条,但安装了同步的 3d 坐标来绘制楔形,这在xyz spherical cs:坐标系中特别容易。

\documentclass[11pt]{standalone}
\usepackage{tikz,amsmath}
\usepackage{tikz-3dplot}

\begin{document}
    %% helper macros

    \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{\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);
    }

    \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);
    }
    \newcommand\DrawLatitudeCircleHalf[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)))}
        \filldraw[current plane] (0,0,0)--(\angVis-45:1) arc (\angVis-45:\angVis-110:1) -- (0,0,0)
    }
    \newcommand\LongitudePlaneHalf[2][current plane]{%
        \pgfmathsinandcos\sinEl\cosEl{\angEl} % elevation
        \pgfmathsinandcos\sint\cost{#2} % azimuth
        \tikzset{#1/.estyle={cm={\cost,\sint*\sinEl,0,\cosEl,(0,0)}}}
    }
    \newcommand\DrawLongitudeCircleHalf[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+127:1);
    }

    %% 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{tikzpicture}%[tdplot_main_coords] % "THE GLOBE" showcase

    \def\R{2.5} % sphere radius
    \def\angEl{35} % elevation angle
    \def\angleLongitudeP{-110} % longitude of point P
    \def\angleLongitudeQ{-45} % longitude of point Q
    \def\angleLatitudeQ{30} % latitude  Q    ; 0 latitude of P 
    \def\angleLongitudeA{-20} % longitude of point A

    \LongitudePlaneHalf[PLongitudePlane]{\angleLongitudeP}
    \LongitudePlaneHalf[QLongitudePlane]{\angleLongitudeQ}
    \LongitudePlaneHalf[ALongitudePlane]{\angleLongitudeA}  
    \draw[] (0,0) circle (\R);
    \foreach \t in {-80,-60,...,80} { \DrawLatitudeCircle[\R]{\t} }
    \foreach \t in {-5,-35,...,-175} { \DrawLongitudeCircle[\R]{\t} }
    \tdplotsetmaincoords{90+\angEl}{-5}
    \begin{scope}[tdplot_main_coords]
    \path (0,0,0) coordinate (O);
    \draw[fill=blue!70] plot[variable=\t,domain=0:90] (xyz spherical cs:radius=\R,longitude=0,latitude=\t) -- (O) -- cycle;
    \draw[fill=blue!50] plot[variable=\t,domain=0:90] (xyz spherical cs:radius=\R,longitude=60,latitude=\t) -- (O) -- cycle;
    \draw[fill=blue!30] plot[variable=\t,domain=0:60] (xyz spherical cs:radius=\R,longitude=\t,latitude=0) -- (O) -- cycle;
    \end{scope}

    \end{tikzpicture}
\end{document} 


\documentclass[tikz,border=2pt]{standalone}
\usetikzlibrary{positioning}
\begin{document}
    \begin{tikzpicture}
    \def\dx{2cm}
    \def\dy{2pt}
    \node (L1) {L1};
    \node[right=\dx of L1] (L2) {L2};
    \node[right=\dx of L2] (L3) {L3};
    \foreach \from/\to/\desc [count=\i from 0,evaluate=\i as \y using {7-\i*\dy} ] in {
        L1/L2/A,
        L2/L3/B,
        L3/L1/C
    } {
        \draw[-stealth,shorten >=1pt] ([yshift=\y]\from.north) -- ([yshift=\y]\to.north) node[midway,label=above:\desc] (N\i) {};
    }
    \foreach \x [count=\i from 0] in {L1,L2,L3} {
        \draw[line width=2pt,shorten >=-1.5pt] (\x) -- (\x |- N\ifnum\i=0 \i\else\the\numexpr\i-1\fi);
    }
    \end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

不使用 3d 包也可以得到同样的结果

 \usepackage{tikz,pgfmath,tkz-euclide}
 \usetikzlibrary{angles}
 \usetkzobj{all}

其中“tkz-euclide”比“tikz”提供了更自然的命令行

通过填充球

 \shade[ball color=orange,opacity=.75] (0,0) circle (2);

并手动绘制必要的路径

  \draw[shade, left color=white, middle color=gray!50!white,top color=orange!60!white,opacity=.5] (P) to[out=90,in=-10,looseness=.8] (Z) to[in=90,out=190,looseness=.8] (Q) to (O) to (P);
  \draw[shade,top color=white,bottom color=orange!20!white,opacity=.5] (Q) to[out=-20,in=200,looseness=.8] (P) to (O);
  \draw[] (P) to[out=90,in=-10,looseness=.8] (Z) to[in=90,out=190,looseness=.8] (Q);

点与点之间

 \tkzDefPoints{0/0/O,0/2/Z,0/-1.5/V2,-2/0/A,2/0/B,0/-.6/i}

尝试

 \begin{tikzpicture}
 \tkzDefPoints{0/0/O,0/2/Z,0/-1.5/V2,-2/0/A,2/0/B,0/-.6/i}
 \tkzDefPoint(210:.95){Q}
 \tkzDefPoint(-25:1.05){P}
 \shade[ball color=orange,opacity=.75] (0,0) circle (2);
 \draw[shade, left color=white, middle color=gray!50!white,top color=orange!60!white,opacity=.5] (P) to[out=90,in=-10,looseness=.8] (Z) to[in=90,out=190,looseness=.8] (Q) to (O) to (P);
 \draw[shade,top color=white,bottom color=orange!20!white,opacity=.5] (Q) to[out=-20,in=200,looseness=.8] (P) to (O);
 \draw[] (P) to[out=90,in=-10,looseness=.8] (Z) to[in=90,out=190,looseness=.8] (Q);
 \tkzDrawSegments(Z,O)
 \tkzMarkAngles[yscale=.7,scale=.6](Q,O,P)
 \tkzDrawSegments[dashed](O,P O,Q)
 \tkzDrawArc[color=black](O,B)(A)
 \tkzDrawArc[color=black](O,A)(B)
 \tkzDrawSegments[bend right](A,B)
 \tkzDrawSegments[bend right,dashed](B,A)
 % to show labels
 %\tkzDrawPoints(O,Q,P,Z)
 %\tkzLabelPoints[above right](O)
 %\tkzLabelPoints[below](Q,P)
 \end{tikzpicture}

产生

在此处输入图片描述

相关内容