我正在尝试做类似的事情图片。我使用了以下例子和问题开始。这是我的代码
\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}
产生