1

I use the formula for 3D-circles. But there is something wrong.

Does anyone feel like scanning the code or has a better solution?

enter image description here

\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} 
cis
  • 8,073
  • 1
  • 16
  • 45
  • What do you mean "there is something wrong"? You have a circle. What are you wanting to happen? – Teepeemm Jul 27 '19 at 03:12
  • 2
    You are making this much more difficult than it has to be. If you really want to draw a rotated ellipse in screen coordinates, it can be done. See https://tex.stackexchange.com/questions/408245/clipping-more-complicated-shapes-in-tikz – John Kormylo Jul 27 '19 at 03:50
  • @JohnKormylo I don not understand how to draw a small circle for a given point M(a, theta, phi) with this. – cis Jul 27 '19 at 09:10
  • @JohnKormylo I do not understand how draw a small circle for a given Point M(a,phi,theta) with that. – cis Jul 27 '19 at 09:55
  • 1
    @cis You can see at here https://tex.stackexchange.com/questions/517062/how-can-i-correct-line-of-the-circle-on-sphere-by-using-3dtools – minhthien_2016 Dec 17 '19 at 12:28

1 Answers1

3

This is so much easier using rotated coordinates. Just play with the angles until (0,0,\R) aligns with (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} 

full page

There is a basic graphics function which can be used to draw the circle using M, P and 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
John Kormylo
  • 79,712
  • 3
  • 50
  • 120
  • Wow very good, John! I tested your code hard: this allows Great Circles too. Nice solution. – cis Jul 27 '19 at 16:59