我有一个球体、一个穿过赤道的圆盘和一个位于赤道上方的红色纬度圆。我想旋转那个红色圆盘,使其与赤道圆盘相交。我该如何实现呢?
如果有帮助,请查看代码下方的图片:我正在尝试模拟“天赤道”上方或下方的“太阳路径”。谢谢。
\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
另一种选择,几乎不需要数学。只需要计算,就可以获得平行线的比例(或半径)。
该示例使用:
- 交叉点和剪辑,针对平行线的可见/不可见部分。
- 层,出于同样的原因。
- 有几种样式可以旋转轴并将其放置在所需的高度。
- 绘制平行线、太阳和常数元素的宏。
最后,需要注意的是:最好不要改变参数(或者不要改变太多)。Ti钾Z 在寻找交点时不是很精确,改变任何东西都可能引起麻烦。
代码:
\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}