How to draw circumsphere of a tetrahedron unknowing center of sphere?

I am trying to draw a sphere passing through four points A, B, C, D of a tetrahedron ABCD. In this code, I have center of sphere is (0,0,0 and radius of sphere is a*sqrt(3).

\documentclass[border=2mm]{standalone}
\usepackage{tikz,tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{120}{55}
\begin{tikzpicture}[tdplot_main_coords,declare function={a=3;}]
\path
(a,a,a) coordinate (B)
(a,-a,-a) coordinate (D)
(-a,a,-a) coordinate (C)
(-a,-a,a) coordinate (A);
\draw[dashed] (A) -- (B) (A) -- (C) (A) -- (D) (B) -- (C) -- (D) (D) -- (B);
\node[circle, fill, inner sep=1pt, label={90:$A$}] at (A) {};
\node[circle, fill, inner sep=1pt, label={60:$B$}] at (B) {};
\node[circle, fill, inner sep=1pt, label={-90:$C$}] at (C) {};
\node[circle, fill, inner sep=1pt, label={90:$D$}] at (D) {};
\draw[tdplot_screen_coords] (0,0,0) circle [radius = a*sqrt(3)];
\end{tikzpicture}
\end{document}


If I have not coordinates of the center of sphere, how can I construct the center and draw sphere?

• You can compute the center and radius given the corners. 4 quadratic equations, 4 unknowns (x,y,z coordinates for the center plus the radius). Commented Nov 21, 2021 at 16:44
• Your sphere and coords are correct, this is an issue of the picture's perspective.
– Dan
Commented Nov 21, 2021 at 17:39
• The center will also lie at the intersection of the perpendicular bisectors (planes) of each of the edges. Commented Nov 21, 2021 at 20:47

We can construct Based on John Kormylo, "The center will also lie at the intersection of the perpendicular bisectors (planes) of each of the edges." In this code, the center will also lie at the intersection of the perpendicular of each of the faces and passing through center of circumcircle of each of the faces.

\documentclass[border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{3dtools}% https://github.com/marmotghost/tikz-3dtools
\begin{document}
\begin{tikzpicture}[line cap=butt,line join=round,3d/install view={phi=235,theta=70,psi=60},declare function={a=3;}]
\path
(a,a,a) coordinate (B)
(a,-a,-a) coordinate (D)
(-a,a,-a) coordinate (C)
(-a,-a,a) coordinate (A);
\path[3d/circumcircle center={A={(A)},B={(B)},C={(C)}}] coordinate (X);
\path[3d/circumcircle center={A={(A)},B={(B)},C={(D)}}] coordinate (Y);
\path[overlay,3d coordinate={(myn1)=(A)-(B)x(A)-(C)},
3d coordinate={(myn2)=(D)-(A)x(D)-(B)}];
\path[3d/line with direction={(myn1) through (X) named d1},
3d/line with direction={(myn2) through (Y) named d2}];
\path[3d/intersection of={d1 with d2}] coordinate (T);
\pgfmathsetmacro{\myR}{sqrt(TD("(T)-(A)o(T)-(A)"))} ;
\draw[dashed] (A) -- (B) (A) -- (C) (A) -- (D) (B) -- (C) -- (D) (D) -- (B);
\path foreach \p/\g in {B/90,C/-90,A/90,D/0,T/0}
{ (\p) node[circle,fill,inner sep=1pt,label=\g:{{$\p$}}]{}};
\end{tikzpicture}
\end{document}


With3dtools, we can use

\path[3d/circumsphere center={A={(A)},B={(B)},C={(C)},D={(D)}}] coordinate (I);


then, I is center of the sphere.

\documentclass[border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{3dtools}% https://github.com/marmotghost/tikz-3dtools
\begin{document}
\begin{tikzpicture}[line cap=butt,line join=round,
3d/install view={phi=235,theta=70,psi=60},declare function={a=3;}]
\path
(a,a,a) coordinate (B)
(a,-a,-a) coordinate (D)
(-a,a,-a) coordinate (C)
(-a,-a,a) coordinate (A);
\path[3d/circumsphere center={A={(A)},B={(B)},C={(C)},D={(D)}}]
coordinate (I);
\pgfmathsetmacro{\myR}{sqrt(TD("(I)-(A)o(I)-(A)"))} ;
\path foreach \p/\g in {B/90,C/-90,A/90,D/0,I/0}
{ (\p) node[circle,fill,inner sep=1pt,label=\g:{{$\p$}}]{}};
\draw[dashed] (A) -- (B) (A) -- (C) (A) -- (D) (B) -- (C) -- (D) (D) -- (B);
\end{tikzpicture}
\end{document}


(It is a long comment, not an answer) Last year, due to low accuracy of TikZ and its limitation for 3D figures, I wrote a plain Asymptote module for both 2D and 3D, named it ESgeometry.asy. Instead of using geometric constructions, it concentrated on using barycentric coordinates (signed area, signed length) and avaiable dot, cross products. Of course it included usual commands such as incenter, inradius, circumcenter, circumradius, .... I minimalized the number of commands by using only 2 main one: ESpoint and ESlength.

triple O=ESpoint("circumcenter",A,B,C,D);


The code has not been cleaned yet. I am going to do it soon.

// a part of ESgeometry.asy (for both 2D and 3D)
triple barycentric(triple A, triple B=(0,0,0), triple C=(0,0,0), triple D=(0,0,0), real a=1, real b=0, real c=0,real d=0){
return (a*A+b*B+c*C+d*D)/(a+b+c+d);
}
//////////////////////////////////////////////
// Compute signed area in 3D
real SignedArea(triple A, triple B, triple C){
return sgn(dot(cross(A,B),C))*abs(cross(B-A,C-A))/2;
}
// Compute (positive) area in 3D
real Area(triple A, triple B, triple C){
return abs(cross(B-A,C-A))/2;
}
triple ESpoint(string name="", triple A, triple B, triple C, triple D){
if (name=="circumcenter") {
triple O1=(abs(A-D))^2*cross(B-D,C-D);
triple O2=(abs(B-D))^2*cross(C-D,A-D);
triple O3=(abs(C-D))^2*cross(A-D,B-D);
real V=dot(A-D,cross(B-D,C-D));
return D+(O1+O2+O3)/(2*V);
}
else if (name=="incenter") {return barycentric(A,B,C,D,Area(B,C,D),Area(C,D,A),Area(D,A,B),Area(A,B,C));}
else if (name=="centroid") {return barycentric(A,B,C,D,1,1,1,1);}
else return (0,0,0);
}
triple ESpoint(string name="", triple A, triple B, triple C){
real a=abs(B-C), b=abs(C-A), c=abs(A-B);
if (name=="footbisector") {return barycentric(A,B,C,0,b,c);}
else if (name=="footaltitude") {return barycentric(A,B,C,0,1/(a^2+c^2-b^2),1/(a^2+b^2-c^2));}
else if (name=="incenter") {return barycentric(A,B,C,a,b,c);}
else if (name=="centroid") {return barycentric(A,B,C,1,1,1);}
else return (0,0,0);
}
///////////////////////////

unitsize(1cm);
import three;
import solids;  // only for better sphere, Circle
triple B=(0,0,0), A=(5,-.5,2), C=(1,3.5,3), D=(1,1,6);
draw(A--B--C--cycle^^D--A^^D--B^^D--C);
label("$A$",A,plain.W);
label("$B$",B,plain.S);
label("$C$",C,plain.E);
label("$D$",D,plain.N);
triple I=ESpoint("incenter",A,B,C,D); dot(I,red);
triple Id=ESpoint("incenter",A,B,C); dot(Id,red);
triple I1=ESpoint("footbisector",A,B,C); dot(I1); draw(A--I1);
triple I2=ESpoint("footaltitude",Id,B,C); dot(I2); draw(Id--I2);
draw(Circle(Id,abs(Id-I2),normal=cross(A-B,A-C)));
real r=abs(I-(I+reflect(A,B,C)*I)/2);
revolution b=sphere(I,r);
draw(surface(b),yellow+opacity(.5));

// the foot of different bisectors
triple Fa=ESpoint("bisectorfoot",A,B,C); dot(Fa,red);
triple Fd=ESpoint("bisectorfoot",D,B,C); dot(Fd,blue);

triple circumcenter(triple A, triple B, triple C, triple D){
triple O1=(abs(A-D))^2*cross(B-D,C-D);
triple O2=(abs(B-D))^2*cross(C-D,A-D);
triple O3=(abs(C-D))^2*cross(A-D,B-D);
real V=dot(A-D,cross(B-D,C-D));
return D+(O1+O2+O3)/(2*V);
}
triple O=ESpoint("circumcenter",A,B,C,D);
revolution Oabcd=sphere(O,abs(O-D));
draw(surface(Oabcd),green+opacity(.3));
dot(A^^B^^C^^D,red);
triple M=barycentric(A,C,.5,.5);
draw(D--M);
triple Mg=barycentric(A,C,D,1,1,1);
dot(Mg,orange);
triple Atest=barycentric(B,1/2); draw(D--Atest);
//draw(shift(D)*surface(plane(A,C)),blue);
//draw(surface(A--B--C--cycle),blue+opacity(.5));
//draw(surface(B--C--D--cycle),red+opacity(.5));
//draw(surface(C--D--A--cycle),magenta+opacity(.5));