tikz-3dplot:按公式绘制球体的小圆 - 找出错误或使其更智能

tikz-3dplot:按公式绘制球体的小圆 - 找出错误或使其更智能

我使用了 3D 圆的公式。但是有些错误。

有人想扫码或者有更好的解决方案吗?

在此处输入图片描述

\documentclass[margin=5mm, tikz]{standalone}
\usepackage{amsmath, amsfonts}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{arrows,calc,backgrounds}
\begin{document}

\pgfmathsetmacro{\R}{3} %  
\pgfmathsetmacro{\a}{1.5} %  

\pgfmathsetmacro{\r}{sqrt(\R^2-\a^2)} %  
%\pgfmathsetmacro{\Alpha}{atan(\r/\a)}   
\pgfmathsetmacro{\Alpha}{acos(\a/\R)} %  

\pgfkeys{/tikz/savevalue/.code 2 args={\global\edef#1{#2}}}

\tdplotsetmaincoords{60}{110}
\begin{tikzpicture}[
tdplot_main_coords,
>=latex, font=\footnotesize,
]

\coordinate[label=$Z$] (Z) at (0,0,0); 

\pgfmathsetmacro{\Teta}{90} %  measured to the z-axis
\pgfmathsetmacro{\Phi}{50} %   measured to the x-axis
% Radius of Small Circle
\pgfmathsetmacro{\xA}{\R*sin(\Teta)*cos(\Phi)} % 
\pgfmathsetmacro{\yA}{\R*sin(\Teta)*sin(\Phi)} % 
\pgfmathsetmacro{\zA}{\R*cos(\Teta)} % 
\coordinate[label=$A$] (A) at (\xA,\yA,\zA); 
\draw[thick] (Z) -- (A);

% Middlepoint of Small Circle
\pgfmathsetmacro{\xM}{\a*sin(\Teta)*cos(\Phi)} % 
\pgfmathsetmacro{\yM}{\a*sin(\Teta)*sin(\Phi)} % 
\pgfmathsetmacro{\zM}{\a*cos(\Teta)} % 
\coordinate[label=$M$] (M) at (\xM,\yM,\zM); 
\draw[red, thick] (Z) -- (M);

% Point P of direction vector p
\pgfmathsetmacro{\xP}{\R*sin(\Teta-\Alpha)*cos(\Phi)} % 
\pgfmathsetmacro{\yP}{\R*sin(\Teta-\Alpha)*sin(\Phi)} % 
\pgfmathsetmacro{\zP}{\R*cos(\Teta-\Alpha)} % 
\coordinate[label=$P$] (P) at (\xP,\yP,\zP); 
\draw[thick] (Z) -- (P);
\draw[->] (M) -- (P);

\path let              
\p0 = (M), % Center
\p1 = (P),
\n1 = {veclen(\y1-\y0,\x1-\x0)},    \n2={atan2(\y1-\y0,\x1-\x0)}
in    [savevalue={\Radius}{\n1}, savevalue={\angle}{\n2}];
\pgfmathsetmacro{\RadiusP}{\Radius/28.4528} % wipe of 'pt' 

% Point Q of direction vector q
\pgfmathsetmacro{\xQ}{\R*sin(\Teta)*cos(\Phi-\Alpha)} % 
\pgfmathsetmacro{\yQ}{\R*sin(\Teta)*sin(\Phi-\Alpha)} % 
\pgfmathsetmacro{\zQ}{\R*cos(\Teta)} % 
\coordinate[label=$Q$] (Q) at (\xQ,\yQ,\zQ); 
\draw[thick] (Z) -- (Q);
\draw[->] (M) -- (Q);

\path let              
\p0 = (M), % Center
\p1 = (Q),
\n1 = {veclen(\y1-\y0,\x1-\x0)},    \n2={atan2(\y1-\y0,\x1-\x0)}
in    [savevalue={\Radius}{\n1}, savevalue={\angle}{\n2}];
\pgfmathsetmacro{\RadiusQ}{\Radius/28.4528} % wipe of 'pt' 

%OLD      
% 3D Small Circle
%\foreach \t in {0,...,360}{
%\pgfmathsetmacro{\rp}{cos(\t)*\r/\RadiusP} %  
%\pgfmathsetmacro{\rq}{sin(\t)*\r/\RadiusQ} %  
%\coordinate[label=$$] (X) at ($(M)+\rp*(P)-\rp*(M)+\rq*(Q)-\rq*(M)$); 
%\draw[red] (X) circle (1pt); 
%}

% NEW:
% 3D Small Circle
% Set Range of angles for drawing points
\def\Range{0,...,360}
\pgfmathsetmacro{\rp}{\r/\RadiusP} %  
\pgfmathsetmacro{\rq}{\r/\RadiusQ} %  

% Create List of Coordinates
\newcommand{\List}{}% reserve name 
\let\List=\empty% create list
\makeatletter
\foreach \t  in \Range
{
\coordinate[label=$$] (X-\t) at ($(M)+cos(\t)*\rp*(P)-cos(\t)*\rp*(M)+sin(\t)*\rq*(Q)-sin(\t)*\rq*(M)$); 
\pgfmathsetmacro\temp{"(X-\t)"}%
  \ifx\empty\List{} \protected@xdef\List{\temp}%
  \else \protected@xdef\List{\List \temp}%
  \fi
}
\makeatother

\draw[red, thick] plot[] coordinates{\List};



% Sphere
\begin{scope}[tdplot_screen_coords, on background layer]
\fill[ball color= gray!20, opacity = 0.3] (Z) circle (\R); 
\end{scope}


\begin{scope}[-latex, shift={(Z)}, xshift=0*2.1*\R cm, yshift=0*0.1*\R cm]
\foreach \P/\s/\Pos in {(5,0,0)/x/right, (0,5,0)/y/below, (0,0,5)/z/right} 
\draw[] (0,0,0) -- \P node (\s) [\Pos, pos=0.9,inner sep=2pt]{$\s$};

\node[above=1cm, align=left, font=\normalsize] at (z){Equation of a 3D-circle: \\
$\vec{x}  = \vec{m} + r \cos(t) \cdot \vec{p} + r \sin(t) \cdot \vec{q}
~~\text{(with $t = 0\dots 2\pi$)}$
};
\end{scope}

\node[anchor=north west, align=left] at (0,-3,-5){
Radius of Sphere: $R = \R$ \\
Distance Small Circle Middlepoint from Sphere Middlepoint: $|ZM| = a = \a$ \\
Angle beetween $\vec{ZM}$ and $\vec{ZP}$: $\alpha=\Alpha^\circ$ \\
Radius of Small Circle: $r = \r$ \\
$|MP|=\RadiusP,~  |MQ|=\RadiusQ$ \\
$r_p = \dfrac{r}{|MP|} = \rp,~    r_q = \dfrac{r}{|MQ|} = \rq$
};
\end{tikzpicture}
\end{document} 

答案1

使用旋转坐标会容易得多。只需调整角度直到(0,0,\R)与对齐即可(A)

\documentclass[margin=5mm, tikz]{standalone}
\usepackage{mathtools}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{arrows,calc,backgrounds}
\begin{document}

\pgfmathsetmacro{\R}{3} %  
\pgfmathsetmacro{\a}{1.5} %  

\pgfmathsetmacro{\r}{sqrt(\R*\R-\a*\a} %  
%\pgfmathsetmacro{\Alpha}{atan(\r/\a)}   
\pgfmathsetmacro{\Alpha}{acos(\a/\R)} %  

\pgfkeys{/tikz/savevalue/.code 2 args={\global\edef#1{#2}}}

\tdplotsetmaincoords{60}{110}
\begin{tikzpicture}[
tdplot_main_coords,
>=latex, font=\footnotesize,
]

\coordinate[label=$Z$] (Z) at (0,0,0); 


\pgfmathsetmacro{\Teta}{90} %  measured to the z-axis
\pgfmathsetmacro{\Phi}{50} %   measured to the x-axis

\tdplotsetrotatedcoords{50}{90}{0}
\begin{scope}[tdplot_rotated_coords]
  \coordinate[label=$A$] (A) at (0,0,\R); 
  \coordinate[label=$M$] (M) at (0,0,\a); 
  \draw[red, thick] (M) circle[radius=\r];
\end{scope}

\draw[thick] (Z) -- (A);
\draw[red, thick] (Z) -- (M);

% Point P of direction vector p
\pgfmathsetmacro{\xP}{\R*sin(\Teta-\Alpha)*cos(\Phi)} % 
\pgfmathsetmacro{\yP}{\R*sin(\Teta-\Alpha)*sin(\Phi)} % 
\pgfmathsetmacro{\zP}{\R*cos(\Teta-\Alpha)} % 
\coordinate[label=$P$] (P) at (\xP,\yP,\zP); 
\draw[thick] (Z) -- (P);
\draw[->] (M) -- (P);

\path let              
\p0 = (M), % Center
\p1 = (P),
\n1 = {veclen(\y1-\y0,\x1-\x0)},    \n2={atan2(\y1-\y0,\x1-\x0)}
in    [savevalue={\Radius}{\n1}, savevalue={\angle}{\n2}];
\pgfmathsetmacro{\RadiusP}{\Radius/28.4528} % wipe of 'pt' 

% Point Q of direction vector q
\pgfmathsetmacro{\xQ}{\R*sin(\Teta)*cos(\Phi-\Alpha)} % 
\pgfmathsetmacro{\yQ}{\R*sin(\Teta)*sin(\Phi-\Alpha)} % 
\pgfmathsetmacro{\zQ}{\R*cos(\Teta)} % 
\coordinate[label=$Q$] (Q) at (\xQ,\yQ,\zQ); 
\draw[thick] (Z) -- (Q);
\draw[->] (M) -- (Q);

\path let              
\p0 = (M), % Center
\p1 = (Q),
\n1 = {veclen(\y1-\y0,\x1-\x0)},    \n2={atan2(\y1-\y0,\x1-\x0)}
in    [savevalue={\Radius}{\n1}, savevalue={\angle}{\n2}];
\pgfmathsetmacro{\RadiusQ}{\Radius/28.4528} % wipe of 'pt' 

%OLD      
% 3D Small Circle
%\foreach \t in {0,...,360}{
%\pgfmathsetmacro{\rp}{cos(\t)*\r/\RadiusP} %  
%\pgfmathsetmacro{\rq}{sin(\t)*\r/\RadiusQ} %  
%\coordinate[label=$$] (X) at ($(M)+\rp*(P)-\rp*(M)+\rq*(Q)-\rq*(M)$); 
%\draw[red] (X) circle (1pt); 
%}

% Sphere
\begin{scope}[tdplot_screen_coords, on background layer]
\fill[ball color= gray!20, opacity = 0.3] (Z) circle (\R); 
\end{scope}


\begin{scope}[-latex, shift={(Z)}, xshift=0*2.1*\R cm, yshift=0*0.1*\R cm]
\foreach \P/\s/\Pos in {(5,0,0)/x/right, (0,5,0)/y/below, (0,0,5)/z/right} 
\draw[] (0,0,0) -- \P node (\s) [\Pos, pos=0.9,inner sep=2pt]{$\s$};

\node[above=1cm, align=left, font=\normalsize] at (z){Equation of a 3D-circle: \\
$\vec{x}  = \vec{m} + r \cos(t) \cdot \vec{p} + r \sin(t) \cdot \vec{q}
~~\text{(with $t = 0\dots 2\pi$)}$
};
\end{scope}

\pgfmathsetmacro{\rp}{\r/\RadiusP} %  
\pgfmathsetmacro{\rq}{\r/\RadiusQ} %  

\node[anchor=north west, align=left] at (0,-3,-5){
Radius of Sphere: $R = \R$ \\
Distance Small Circle Middlepoint from Sphere Middlepoint: $|ZM| = a = \a$ \\
Angle beetween $\vec{ZM}$ and $\vec{ZP}$: $\alpha=\Alpha^\circ$ \\
Radius of Small Circle: $r = \r$ \\
$|MP|=\RadiusP,~  |MQ|=\RadiusQ$ \\
$r_p = \dfrac{r}{|MP|} = \rp,~    r_q = \dfrac{r}{|MQ|} = \rq$
};
\end{tikzpicture}
\end{document} 

完整页面

有一个基本的图形函数,可以用来使用MP和绘制圆形Q

\pgfscope
\color{blue}%
\pgfpathellipse{\pgfpointanchor{M}{center}}%
  {\pgfpointdiff{\pgfpointanchor{M}{center}}{\pgfpointanchor{P}{center}}}%
  {\pgfpointdiff{\pgfpointanchor{M}{center}}{\pgfpointanchor{Q}{center}}}%
\pgfusepath{draw}%
\endpgfscope

相关内容