如何在不知道球心的情况下画出四面体的外接球?

如何在不知道球心的情况下画出四面体的外接球?

我正在尝试绘制一个通过A, B, C, D四面体的四个点的球体ABCD。在此代码中,球心为(0,0,0,球半径为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}

在此处输入图片描述

如果我没有球心的坐标,我该如何构造中心并绘制球体?

答案1

我们可以基于 John Kormylo 构建,“中心也将位于每个边的垂直平分线(平面)的交点处。” 在此代码中,中心也将位于每个面的垂直线的交点处,并穿过每个面的外接圆中心。

\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[3d/screen coords] (T) circle[radius=\myR]; 
        \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}

在此处输入图片描述

有了3dtools,我们可以使用

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

那么,I 就是球体的中心。

\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)"))} ;  
    \draw[3d/screen coords] (I) circle[radius=\myR]; 
    \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}

答案2

(这是一条长评论,不是答案)去年,由于 TikZ 的精度低以及对 3D 图形的限制,我为 2D 和 3D 编写了一个普通的 Asymptote 模块,将其命名为ESgeometry.asy。它不使用几何构造,而是专注于使用barycentric coordinatessigned areasigned length)和可用的dotcross products。当然,它包括常用命令,例如incenterinradiuscircumcentercircumradius,... 。我通过使用仅 2 个主要命令来最小化命令数量:ESpointESlength

triple O=ESpoint("circumcenter",A,B,C,D);
real R=ESlength("circumradius",A,B,C,D);

代码还没有清理。我很快就会清理。

在此处输入图片描述

// 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));

相关内容