# How can I draw a circle knowing center and radius lies on a plane?

My problem is: Let be given pyramid SABC with AC = 5a, AB = 4a, BC = 3a, SA is perpendicular to the plane (ABC), SA = h; E is projection of A on SB, F is projection of A on SC. Four points E, F, C, B lie on a circle with center is midpoint of the segment EC and radius equal to EC/2.

Based on the question, How to draw a circle (sphere) passing through four points?

I tried

\documentclass[border=2 mm,12pt,tikz]{standalone}
\usepackage{tikz,tikz-3dplot}
\usepackage{tkz-euclide}
\usetkzobj{all}
\usetikzlibrary{intersections,calc,backgrounds}
% based on tex.stackexchange.com/a/12033/…
\tikzset{reverseclip/.style={insert path={(current bounding box.south west)rectangle
(current bounding box.north east)} }}

\usetikzlibrary{calc,through}
\tikzset{circle through 3 points/.style n args={3}{%
insert path={let \p1=($(#1)!0.5!(#2)$),
\p2=($(#1)!0.5!(#3)$),
\p3=($(#1)!0.5!(#2)!1!-90:(#2)$),
\p4=($(#1)!0.5!(#3)!1!90:(#3)$),
\p5=(intersection of \p1--\p3 and \p2--\p4)
in },
at={(\p5)},
circle through= {(#1)}
}}

\usetikzlibrary{intersections,calc,backgrounds}

\begin{document}
\tdplotsetmaincoords{70}{60}

\begin{tikzpicture}[tdplot_main_coords,scale=1]
\pgfmathsetmacro\a{1}
\pgfmathsetmacro\h{6}

% definitions
\path
coordinate(A) at (0,0,0)
coordinate (B) at (4*\a,0,0)
coordinate (C) at (4*\a,3*\a,0)
coordinate (S) at (0,0,\h)
coordinate (E) at ({4*\h^2*\a/(16*\a^2+\h^2)}, 0, {16*\h*\a^2/(16*\a^2+\h^2)})
coordinate (F) at ({4*\h^2*\a/(25*\a^2+\h^2)}, {3*\h^2*\a/(25*\a^2+\h^2)}, {25*\h*\a^2/(25*\a^2+\h^2)});
\begin{scope}
\draw[dashed,thick]
(A) -- (C) ;
\draw[thick]
(S) -- (B) (S)-- (A) -- (B)-- (C) -- cycle (A) --(E) (A) --(F);
\end{scope}
\foreach \point/\position in {A/left,B/below,C/right,S/above,E/right,F/below}
{
\fill[black] (\point) circle (1.5pt);
\node[\position=1.5pt] at (\point) {$\point$};
}
\node[circle through 3 points={F}{E}{B},draw=blue,dotted]{};
\end{tikzpicture}
\end{document}


But, I got a circle didn't pass four points.

How can I draw the circle like this picture? Or it can be view every angle in 3D?

Here is another proposal using the corresponding pic from the experimental 3dtools library. There is no guarantee that it always works, but it seems to work here. A simple analytic discussion can be found here.

\documentclass[border=2 mm,12pt,tikz]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{3dtools}
\begin{document}
\tdplotsetmaincoords{70}{60}
\begin{tikzpicture}[tdplot_main_coords,scale=1]
\pgfmathsetmacro\a{1}
\pgfmathsetmacro\h{6}

% definitions
\path
(0,0,0)  coordinate(A)
(4*\a,0,0)  coordinate (B)
(4*\a,3*\a,0)  coordinate (C)
(0,0,\h)  coordinate (S)
({4*\h^2*\a/(16*\a^2+\h^2)}, 0, {16*\h*\a^2/(16*\a^2+\h^2)})  coordinate (E)
({4*\h^2*\a/(25*\a^2+\h^2)}, {3*\h^2*\a/(25*\a^2+\h^2)}, {25*\h*\a^2/(25*\a^2+\h^2)})
coordinate (F);
\begin{scope}
\draw[dashed,thick]
(A) -- (C) ;
\draw[thick]
(S) -- (B) (S)-- (A) -- (B)-- (C) -- cycle (A) --(E) (A) --(F);
\end{scope}
\foreach \point/\position in {A/left,B/below,C/right,S/above,E/right,F/below}
{
\fill[black] (\point) circle (1.5pt);
\node[\position=1.5pt] at (\point) {$\point$};
}
\pic[draw=blue,thick]{3d circle through 3 points={A={(E)},B={(B)},C={(C)}}};
\end{tikzpicture}
\end{document}


• It is incorect when I try to draw the circle through 3 points S, B, D at here tex.stackexchange.com/questions/510620/… Oct 18, 2019 at 5:45
• tex.stackexchange.com/questions/510620/… , It is true with two circles \pic[draw=blue,thick]{3d circle through 3 points={A={(S)},B={(B)},C={(C)}}}; \pic[draw=red,thick]{3d circle through 3 points={A={(S)},B={(A)},C={(C)}}}; Oct 18, 2019 at 5:56
• @minhthien_2016 Yes, there was a hard coded coordinate C in the library. I fixed it.
– user194703
Oct 18, 2019 at 6:00
• When I updated 3dtools, I can't compile the above file. Oct 18, 2019 at 7:04
• @minhthien_2016 I have updated the library. Unfortunately I will again be offline for a while.
– user194703
Oct 18, 2019 at 16:42

To draw the circle, we need to switch to the plane in which B, C and E (and here also F) sit, and to compute the center and the radius of the circle. This answer focuses on how to transform the coordinate system (since you seem to know the center and the radius and the question how to get that coordinate system has a surprisingly simple answer).

Call the normalized normal vector of the plane n. We need to find rotation angles in such a way that the rotated z axis coincides with n. However, the rotated z axis is simply

 D.(0,0,1)


where the rotation matrix D is given on p. 7 of the tikz-3dplot manual

So we need to solve

   (0)   (nx)
D |0| = |ny|
(1)   (nz)


which has the solution

beta  = arccos(nz)
alpha = arccos(nx/sin(beta))


For the users convenience, the circles can be inserted via a style

  \draw[red,thick,circle in plane with normal={{\mynormal} with radius {\r} around (I)}];


This style also comes with a correction. The earlier version of the answer sometimes yielded wrong output, with the reason being as simple as a sign reflecting that cos(x)=cos(-x) (GRRRR). Neither the centers nor the radii of the circles are computed here, I got them all out of our chat. Sorry for the sign mistake!

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{3d}
\usetikzlibrary{calc}
\makeatletter
\newcounter{smuggle}
\DeclareRobustCommand\smuggleone[1]{%
\stepcounter{smuggle}%
\expandafter\global\expandafter\let\csname smuggle@\arabic{smuggle}\endcsname#1%
\aftergroup\let\aftergroup#1\expandafter\aftergroup\csname smuggle@\arabic{smuggle}\endcsname
}
\DeclareRobustCommand\smuggle[2][1]{%
\smuggleone{#2}%
\ifnum#1>1
\aftergroup\smuggle\aftergroup[\expandafter\aftergroup\the\numexpr#1-1\aftergroup]\aftergroup#2%
\fi
}
\makeatother
\def\parsecoord(#1,#2,#3)>(#4,#5,#6){%
\def#4{#1}%
\def#5{#2}%
\def#6{#3}%
\smuggle{#4}%
\smuggle{#5}%
\smuggle{#6}%
}
\def\SPTD(#1,#2,#3).(#4,#5,#6){((#1)*(#4)+1*(#2)*(#5)+1*(#3)*(#6))}
\def\VPTD(#1,#2,#3)x(#4,#5,#6){((#2)*(#6)-1*(#3)*(#5),(#3)*(#4)-1*(#1)*(#6),(#1)*(#5)-1*(#2)*(#4))}
\def\VecMinus(#1,#2,#3)-(#4,#5,#6){(#1-1*(#4),#2-1*(#5),#3-1*(#6))}
\newcommand{\RotationAnglesForPlaneWithNormal}[5]{%\typeout{N=(#1,#2,#3)}
\foreach \XS in {1,-1}
{\foreach \YS in {1,-1}
{\pgfmathsetmacro{\mybeta}{\XS*acos(#3)}
\pgfmathsetmacro{\myalpha}{\YS*acos(#1/sin(\mybeta))}
\pgfmathsetmacro{\ntest}{abs(cos(\myalpha)*sin(\mybeta)-#1)%
+abs(sin(\myalpha)*sin(\mybeta)-#2)+abs(cos(\mybeta)-#3)}
\ifdim\ntest pt<0.1pt
\xdef#4{\myalpha}
\xdef#5{\mybeta}
\fi
}}
}
\tikzset{circle in plane with normal/.style args={#1 with radius #2 around #3}{
/utils/exec={\edef\temp{\noexpand\parsecoord#1>(\noexpand\myNx,\noexpand\myNy,\noexpand\myNz)}
\temp
\pgfmathsetmacro{\myNx}{\myNx}
\pgfmathsetmacro{\myNy}{\myNy}
\pgfmathsetmacro{\myNz}{\myNz}
\pgfmathsetmacro{\myNormalization}{sqrt(pow(\myNx,2)+pow(\myNy,2)+pow(\myNz,2))}
\pgfmathsetmacro{\myNx}{\myNx/\myNormalization}
\pgfmathsetmacro{\myNy}{\myNy/\myNormalization}
\pgfmathsetmacro{\myNz}{\myNz/\myNormalization}
% compute the rotation angles that transform us in the corresponding plabe
\RotationAnglesForPlaneWithNormal{\myNx}{\myNy}{\myNz}{\tmpalpha}{\tmpbeta}
%\typeout{N=(\myNx,\myNy,\myNz),alpha=\tmpalpha,beta=\tmpbeta,r=#2,#3}
\tdplotsetrotatedcoords{\tmpalpha}{\tmpbeta}{0}},
insert path={[tdplot_rotated_coords,canvas is xy plane at z=0,transform shape]
}}

\begin{document}
\foreach \X in  {5,15,...,355} %  {50}%
{\tdplotsetmaincoords{70}{\X}
\begin{tikzpicture}[tdplot_main_coords,scale=1]
\path [tdplot_screen_coords,use as bounding box] (-7,-3) rectangle (7,7);
\pgfmathsetmacro\a{1}
\pgfmathsetmacro\h{7}
\pgfmathsetmacro\rprime{5*sqrt(\a^2*\h^2/(25*\a^2+\h^2))*(1/2))}
\pgfmathsetmacro\r{(1/2)*sqrt((400*\a^4+9*\a^2*\h^2)/(16*\a^2+\h^2))}
% definitions
\path
coordinate(A) at (0,0,0)
coordinate (B) at (4*\a,0,0)
coordinate (C) at (4*\a,3*\a,0)
coordinate (S) at (0,0,\h)
coordinate (E) at ({4*\h^2*\a/(16*\a^2+\h^2)}, 0, {16*\h*\a^2/(16*\a^2+\h^2)})
coordinate (F) at ({4*\h^2*\a/(25*\a^2+\h^2)}, {3*\h^2*\a/(25*\a^2+\h^2)},{25*\h*\a^2/(25*\a^2+\h^2)})
coordinate (I') at ($(F)!0.5!(A)$)
coordinate (I) at ($(C)!0.5!(E)$);
\begin{scope}
\draw[dashed,thick]
(A) -- (C) ;
\draw[thick]
(S) -- (B) (S)-- (A) -- (B)-- (C) -- cycle (A) --(E) (A) --(F);
\end{scope}
\foreach \point/\position in {A/left,B/below,C/right,S/above,E/right,F/below}
{
\fill[black] (\point) circle (1.5pt);
\node[\position=1.5pt] at (\point) {$\point$};
}

% % store the coordinates of E, A and F in marcros
\parsecoord({4*\h^2*\a/(16*\a^2+\h^2)},0,{16*\h*\a^2/(16*\a^2+\h^2)})>(\myEx,\myEy,\myEz)
\parsecoord(0,0,0)>(\myAx,\myAy,\myAz)
\parsecoord({4*\h^2*\a/(25*\a^2+\h^2)},{3*\h^2*\a/(25*\a^2+\h^2)},{25*\h*\a^2/(25*\a^2+\h^2)})>(\myFx,\myFy,\myFz)
\parsecoord(4*\a,0,0)>(\myBx,\myBy,\myBz)
\parsecoord(4*\a,3*\a,0)>(\myCx,\myCy,\myCz)
% % compute the normal of the plane in which E, B and C sit
\def\mynormal{\VPTD({\myEx-\myAx},{\myEy-\myAy},{\myEz-\myAz})x({\myFx-\myAx},{\myFy-\myAy},{\myFz-\myAz})}
\edef\temp{\noexpand\parsecoord\mynormal>(\noexpand\myNx,\noexpand\myNy,\noexpand\myNz)}
\draw[blue,thick,circle in plane with normal={{\mynormal} with radius {\rprime}
around (I')}];
\def\mynormal{\VPTD({\myEx-\myBx},{\myEy-\myBy},{\myEz-\myBz})x({\myCx-\myBx},{\myCy-\myBy},{\myCz-\myBz})}
\draw[red,thick,circle in plane with normal={{\mynormal} with radius {\r}
around (I)}];
\node[anchor=north east] at (current bounding box.north east) {$\theta=\tdplotmaintheta^\circ,\phi=\tdplotmainphi^\circ$};
\end{tikzpicture}}
\end{document}


Notes: (i) to myself this trick may be important for the analytic discrimination of hidden vs. visible parts of objects. If I rediscover this one day, I can at least claim I knew that before. (ii) whoever tries to further develop this very nice answer may find this useful.

• I must find the formula of the rotation matrix D: fantastic! Mar 28, 2019 at 16:38
• suggestion : AC and AF should be dashed when behind, i.e. before 135° and after 315° (approximately), AB and AE should be dashed between 100° and 280° (approximately), and so on for the others ;)
– Kpym
Mar 30, 2019 at 5:42
• I am very intersecting in this answer. Jul 29, 2019 at 1:22

This is a, "over simplified" answer compared to @marmot's one but I put it here because it can be useful to see how we can use canvas is plane to draw in a slanted 3d plane.

\documentclass[tikz,border=7pt]{standalone}
\usetikzlibrary{calc,3d,angles}
\tikzstyle{*}=[nodes=circle,label={center,scale=2:.},label={#1}]
\begin{document}
\begin{tikzpicture}
\def\h{7} % the length of AS
% define the view point
\path let \n{azimuth}={49}, \n{inclination}={14} in
coordinate (X) at ({cos(\n{azimuth})},{sin(\n{inclination})*sin(-\n{azimuth})})
coordinate (Y) at ({sin(\n{azimuth})},{sin(\n{inclination})*cos(\n{azimuth})})
coordinate (Z) at ({0},{cos(\n{inclination})})
;
\begin{scope}[x={(X)},y={(Y)},z={(Z)}]
% Place the points A,B,C,S and draw some edges
\draw
(0,0,0) coordinate[*=below left:A](A) --
(3,0,0) coordinate[*=below left:B](B) --
(3,4,0) coordinate[*=below right:C](C) --
(0,0,\h) coordinate[*=above left:S](S) --
(B) (S) -- (A) edge[dashed] (C)
;
% Find the point E and draw AE
\begin{scope}[
plane origin={(0,0,0)}, % A
plane x={(1,0,0)}, % A + unit vector in direction of AB
plane y={(0,0,1)}, % A + unit vector in direction of AS
canvas is plane,
]
\draw ($(B)!(A)!(S)$) coordinate[*=above left:E](E) -- (A);
\end{scope}
% Find the point F and draw AE
\begin{scope}[
plane origin={(0,0,0)}, % A
plane x={(3/5,4/5,0)}, % A + unit vector in direction of AC
plane y={(0,0,1)}, % A + unit vector in direction of AS
canvas is plane,
]
\draw[dashed] ($(C)!(A)!(S)$) coordinate[*=above right:F](F) -- (A);
\end{scope}
% Draw the circle
\pgfmathsetmacro\u{sqrt(9+\h*\h)}
\begin{scope}[
plane origin={(3,0,0)}, % B
plane x={(3,1,0)}, % B + unit vector (0,1,0) in direction BC
plane y={(3-3/\u,0,\h/\u)}, % B + unit vector (-3/\u,0,\h/\u) in direction BS (-3,0,\h)
canvas is plane,
]

\pgfmathparse{sqrt(20.25/(9+\h*\h)+4)} % sqrt(3^4/(3^2+\h^2)+4^2)/2 by Pythagoras
\draw[blue] ($(C)!.5!(E)$) circle(\pgfmathresult);
\end{scope}
% mark some right angles
pic[draw=red]{right angle=C--B--A}
pic[draw=red]{right angle=A--E--B}
pic[draw=red]{right angle=A--F--C}
pic[draw=red]{right angle=B--A--S}
;
\end{scope}
\end{tikzpicture}
\end{document}


Note: For me the interesting part of this answer is that one can draw inside an arbitrary inclined plane with the usual tools: orthogonal projection of calc, circle, pic{right angle}, ... using canvas is plane of 3d to avoid complex isometric transforms.

History:

• In the first version of this answer, I claimed that the 3d is new, which, as @marmot points out in a comment, is false, it simply hasn't been documented since 2019 (version 3.1)
• I also didn't mention the previous use of 3d in @marmot's answer, for which I apologize.
• Another criticism of @marmot was that my calculations were done "by hand" and that my projection was not orthographic. So I modified my answer to take into account these criticisms and put parameters for the position of S and for the point of view (but I kept some lengths constant as requested in the OP).
• Sorry, do you know what an orthographic projection is?
– user121799
Mar 30, 2019 at 14:32
• In this case I'll replace "new" by "recently documented" (but for me something that is not documented is not officially usable). The "hard" part of this picture is to decide what ellipse represent the circle, and this is not done "by hand", but drawing a circle in the right canvas is plane . No need of complex 3d transforms ;)
– Kpym
Mar 30, 2019 at 14:35
• Seems you haven't even looked at my code. I do draw the circles in planes, which is why there is a canvas is xy plane at z=0. (And yes, canvas is xy plane did get fixed recently, the other planes worked properly before.) My transformations are by no means more complex than yours since I only use the normal of a plane to define a plane, not like you two vectors which span it. (Both options are fine, of course.) The real difference is that I am using orthographic projections, which are defined by angles. Your code distorts the view.
– user121799
Mar 30, 2019 at 14:40
• @marmot To be honest, yes, I haven't even looked at your code : it is too complex for me. I like short codes ;) And if my projection is orthographic or not depends only on the choice of x, y and z. But one more time yes, in my case I have chosen them by hand, so it is not orthographic.
– Kpym
Mar 30, 2019 at 14:47

I tried with 3dtools

\documentclass[border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{3dtools}% https://github.com/marmotghost/tikz-3dtools
\begin{document}
\begin{tikzpicture}[line cap=round,line join=round,c/.style={circle,fill,inner sep=1pt},3d/install view={phi=200,theta=65},declare function={a=1;h=5;}]
\path
(0,0,0) coordinate (A)
(4*a,0,0) coordinate (B)
(0,3*a,0) coordinate (C)
(0,0,h) coordinate (S);
\path[3d/line through={(S) and (B) named lSB} ]
[3d/line through={(S) and (C) named lSC} ]
[3d/project={(A) on lSB}] coordinate (E)
[3d/project={(A) on lSC}] coordinate (F);
\pic[red]{3d circle through 3 points={%
A={(E)},B={(B)},C={(F)},center name=I}};
\path foreach \p/\g in {S/90,A/-90,B/180,C/-90,E/120,F/180,I/-90}
{(\p)node[c]{}+(\g:2.5mm) node{$\p$}};
\draw[3d/hidden] (A) -- (E) (A) -- (B);
\draw[3d/visible] (S)--(B)--(C)--cycle  (A) --(F) --  (E) (S) -- (A) -- (C);
\end{tikzpicture}
\end{document}