如何改变球体上纬度圈的方向?

如何改变球体上纬度圈的方向?

我有一个球体、一个穿过赤道的圆盘和一个位于赤道上方的红色纬度圆。我想旋转那个红色圆盘,使其与赤道圆盘相交。我该如何实现呢?

如果有帮助,请查看代码下方的图片:我正在尝试模拟“天赤道”上方或下方的“太阳路径”。谢谢。

\documentclass[12pt]{article}
\usepackage{tikz}
\usetikzlibrary{positioning}

\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/.estyle={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/.estyle={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,thin] (\angVis:1) arc (\angVis:\angVis+180:1);
  \draw[current plane,thin,dashed] (\angVis-180:1) arc (\angVis-180:\angVis:1);
}%this is fake: for drawing the grid



\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,thick,red] (\angVis:1) arc (\angVis:-\angVis-180:1);
  \draw[current plane,thick,dashed,red] (180-\angVis:1) arc (180-\angVis:\angVis:1);
}

\newcommand\FillLatitudeCircle[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)))}
  \fill[current plane,black,opacity=0.3] (\angVis:1) arc (\angVis:-\angVis-180:1);
  \fill[current plane,black,opacity=0.3] (180-\angVis:1) arc (180-\angVis:\angVis:1);
}

\usepackage{amsmath}
\usetikzlibrary{arrows}
\pagestyle{empty}
\usepackage{pgfplots}
\usetikzlibrary{calc,fadings,decorations.pathreplacing}

\begin{document}
\begin{figure}[ht!]
\begin{tikzpicture}[scale=1,every node/.style={minimum size=1cm}]
    
    \def\R{4} % sphere radius
    \def\angEl{15} % elevation angle
    \def\angBeta{30} % latitude of point P and Q
    
    \fill[ball color=white!10] (0,0) circle (\R); % 3D lighting 

    \DrawLongitudeCircle[\R]{-45} % qzplane
    %\DrawLatitudeCircle[\R]{\angBeta}
    \DrawLatitudeCircle[\R]{35}
    %\DrawLatitudeCircle[\R]{60}
    % \DrawLatitudeCircle[\R]{0} % equator
    \FillLatitudeCircle[\R]{0} % equator

\end{tikzpicture}
\end{figure}
\end{document}

太阳在天球上的路径

答案1

另一种选择,几乎不需要数学。只需要计算,就可以获得平行线的比例(或半径)。

该示例使用:

  1. 交叉点和剪辑,针对平行线的可见/不可见部分。
  2. 层,出于同样的原因。
  3. 有几种样式可以旋转轴并将其放置在所需的高度。
  4. 绘制平行线、太阳和常数元素的宏。

最后,需要注意的是:最好不要改变参数(或者不要改变太多)。TiZ 在寻找交点时不是很精确,改变任何东西都可能引起麻烦。

代码:

\documentclass[tikz,border=2mm]{standalone}
\usepackage{fontawesome} % for \faMale
\usetikzlibrary{3d,intersections,perspective}

% layers
\pgfdeclarelayer{back}
\pgfsetlayers{back,main}

\pgfmathsetmacro\azimuth{82}
\tikzset
{% styles
   rotated/.style={rotate around x=50},
   rotated at height/.style={rotated,canvas is xy plane at z=#1,%
                             rotate around z=-\azimuth,scale={0.5*sqrt(4-#1*#1)}},
   rotated at height/.default=0,
}

\NewDocumentCommand{\celestial}{}
{% draws all the constant elements
   \path[name path=sphere]  (0,0,0) circle (2cm);
   \draw[rotated,blue!50]   (0,0,0) -- (0,0,-2);
   \fill[top color=orange!40!red,bottom color=orange,canvas is xy plane at z=0] (0,0) circle (2);
   \fill[shading=ball,ball color=gray,fill opacity=0.2] (0,0,0) circle (2cm);
   \draw[rotated,blue!50]   (0,0,0) -- (0,0,2);
   \draw[rotated,blue]      (0,0,2) -- (0,0,3) node[midway,pin={[align=left,black]90:{North\\celestial\\pole}}]  {};;
   \node[inner sep=0,anchor=south]  at (0,0) {\faMale};
   \node[below right] at (2,0)    {W};
   \node[right]       at (2cm,0)  {S};
   \node[above left]  at (-2,0)   {E};
   \node[left]        at (-2cm,0) {N};
   \node[rotated,pin={[align=left]260:{Celestial\\equator}}] at (270:2) {};
}

\NewDocumentCommand{\cparallel}{O{0}mo}
{% draws a parallel
 % #1 = height between -0.5 and 0.5 (default 0, equator)
 % #2 = format
 % #3 = date
   \begin{scope}[rotated at height=2*#1]
     \pgfmathsetmacro\b{3}
     \path[name path=circle] (0,0) circle (2);
     \path[name intersections={of=sphere and circle}];
     \coordinate (date) at (180:2);
     \begin{pgfonlayer}{back}
       \begin{scope}
         \clip[overlay] (intersection-1) -- (intersection-2) --++ (1,-3) --++ (-6,0) -- cycle;
         \draw[#2]      (0,0) circle (2);
       \end{scope}
     \end{pgfonlayer}
     \clip[overlay]     (intersection-1) -- (intersection-2) --++ (1, 3) --++ (-6,0) -- cycle;
     \draw[#2]          (0,0) circle (2);
   \end{scope}
   \IfNoValueF{#3}{\node[pin={[align=left]70:{Sun's path\\#3}}] at (date) {};}
}

\NewDocumentCommand{\csun}{O{0}m}
{% draws the sun
 % #1 = height between -0.5 and 0.5 (default 0, equator)
 % #2 = sun position (angle)
   \begin{scope}[rotated at height=2*#1]
     \coordinate (sun) at (#2:2);
   \end{scope}
   \fill[ball color=yellow] (sun) circle (0.05cm);
}

\begin{document}
\begin{tikzpicture}[line cap=round,font=\sffamily,3d view={\azimuth}{20}]
% left
\celestial
\cparallel{green,dashed}
\cparallel[0.5]{green}[June 21]
\csun[0.5]{260}
% center
\begin{scope}[shift={(\azimuth:6)}]
  \celestial
  \cparallel{green}[March 21\\Sept. 21]
  \csun{250}
\end{scope}
% right
\begin{scope}[shift={(\azimuth:12)}]
  \celestial
  \cparallel[-0.5]{green}[Dec. 21]
  \cparallel{dashed,green}
  \csun[-0.5]{220}
\end{scope}
\end{tikzpicture}
\end{document}

输出结果如下:

在此处输入图片描述

答案2

开始scope并在该范围内旋转纬度圈。

\documentclass[12pt]{article}
\usepackage{tikz}
\usetikzlibrary{positioning}

\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/.estyle={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/.estyle={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,thin] (\angVis:1) arc (\angVis:\angVis+180:1);
  \draw[current plane,thin,dashed] (\angVis-180:1) arc (\angVis-180:\angVis:1);
}%this is fake: for drawing the grid



\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,thick,red] (\angVis:1) arc (\angVis:-\angVis-180:1);
  \draw[current plane,thick,dashed,red] (180-\angVis:1) arc (180-\angVis:\angVis:1);
}

\newcommand\FillLatitudeCircle[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)))}
  \fill[current plane,black,opacity=0.3] (\angVis:1) arc (\angVis:-\angVis-180:1);
  \fill[current plane,black,opacity=0.3] (180-\angVis:1) arc (180-\angVis:\angVis:1);
}

\usepackage{amsmath}
\usetikzlibrary{arrows}
\pagestyle{empty}
\usepackage{pgfplots}
\usetikzlibrary{calc,fadings,decorations.pathreplacing}

\begin{document}
\begin{figure}[ht!]
\begin{tikzpicture}[scale=1,every node/.style={minimum size=1cm}]
    
    \def\R{4} % sphere radius
    \def\angEl{15} % elevation angle
    \def\angBeta{30} % latitude of point P and Q
    
    \fill[ball color=white!10] (0,0) circle (\R); % 3D lighting 

    \DrawLongitudeCircle[\R]{-45} % qzplane
    %\DrawLatitudeCircle[\R]{\angBeta}
    
\begin{scope}[rotate=45]
    \DrawLatitudeCircle[\R]{15}
\end{scope}

    %\DrawLatitudeCircle[\R]{60}
    % \DrawLatitudeCircle[\R]{0} % equator
    \FillLatitudeCircle[\R]{0} % equator

\end{tikzpicture}
\end{figure}
\end{document}

相关内容