设是四面体SABC
,其中AB= 3, AC=4, BC=5, SA= 6, SB=7,SC=8
。我试过了
\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{60}{70}
\begin{tikzpicture} [tdplot_main_coords,c/.style={circle,fill,inner sep=1pt}]
\path
(0,0,0) coordinate (A)
(3,0,0) coordinate (B)
(0, 4,0) coordinate (C)
;
\draw (C) -- (A) -- (B) -- cycle;
\path foreach \p/\g in {A/180,B/0,C/90}{(\p)node[c]{}+(\g:2.5mm) node{$\p$}};
\end{tikzpicture}
\end{document}
如何得到要点S
?
答案1
更新 通过使用新更新
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{calc,3dtools} % https://github.com/marmotghost/tikz-3dtools
\begin{document}
\begin{tikzpicture}[line cap=round,line join=round,c/.style={circle,fill,inner sep=1pt},
declare function={lAB=3;lAC=4;lBC=5;lAD=6;lBD=7;lCD=8;}]
% ^^^ the lengths of the tetrahedron
\begin{scope}[3d/install view={phi=100,psi=0,theta=70}]
% construct a triangle of three vertices in the xy plane
% using the cosine law
\pgfmathsetmacro{\mytheta}{acos(-1*(lBC*lBC-lAC*lAC-lAB*lAB)/(2*lAB*lAC))}
\path (0,0,0) coordinate (A)
(lAB,0,0) coordinate (B)
({lAC*cos(\mytheta)},{lAC*sin(\mytheta)},0) coordinate (C);
\path[overlay,3d/aux keys/i1=S,3d/aux keys/i2=D',
3d/intersection of three spheres={rA=lAD,rB=lBD,rC=lCD}];
\path[3d/circumsphere center={A={(A)},B={(B)},C={(C)},D={(S)}}]
coordinate (I);
\pgfmathsetmacro{\myR}{sqrt(TD("(I)-(A)o(I)-(A)"))} ;
\path[3d/circumcircle center={A={(A)},B={(B)},C={(C)}}] coordinate (G);
\draw[red,3d/screen coords] (I) circle[radius=\myR];
\path pic{3d/circle on sphere={R=\myR,C={(I)}, P={(G)}}};
\path[3d/circumcircle center={A={(A)},B={(B)},C={(S)}}] coordinate (T);
\path[blue] pic{3d/circle on sphere={R=\myR,C={(I)}, P={(T)}}};
\path foreach \p/\g in {A/180,B/-90,C/0,S/90,G/-90,I/0}{(\p)node[c]{}+(\g:2.5mm) node{$\p$}};
\draw[3d/hidden] (A) -- (C) (S) -- (A) (S) -- (B) (S) --(C) (A) -- (B) -- (C);
\end{scope}
\end{tikzpicture}
\end{document}
请注意,有两点S
。我把它们放在S
和S'
。您可以使用3d工具。在此代码中,我添加了两个点T
,T'
可以通过 Maple 找到并与 的结果进行比较3dtools
。
\documentclass[border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{3dtools,calc}% https://github.com/marmotghost/tikz-3dtools
\begin{document}
\begin{tikzpicture}[3d/install view={phi=70,theta=70},line cap=butt,line join=round,c/.style={circle,fill,inner sep=1pt},declare function={r1=6;r2=7;r3=8;}]
\path
(0,0,0) coordinate (A)
(3,0,0) coordinate (B)
(0,4,0) coordinate (C)
(-2/3,-3/2,{sqrt(1199)/6}) coordinate (T)
(-2/3,-3/2,{-sqrt(1199)/6}) coordinate (T')
; % T and T' are found by Maple
\path[overlay,3d/aux keys/i1=S,3d/aux keys/i2=S',3d/intersection of three spheres={rA=r1,rB=r2,rC=r3}];
\path foreach \p/\g in {A/180,B/-90,C/-90,S/0,T/180,S'/0,T'/180}
{(\p)node[c]{}+(\g:2.5mm) node{$\p$}};
\end{tikzpicture}
\end{document}
答案2
更新:计算来自三维笛卡尔真距多点定位(实际上,这些是计算三个球面交点的公式。)我还在 XY 平面上添加了 3D 网格。
unitsize(1cm);
import three;
import grid3;
triple barycentric(triple A, triple B, triple C, real a, real b, real c){return (a*A+b*B+c*C)/(a+b+c);}
currentprojection=orthographic((1,1,.8),center=true,zoom=.9);
// Step 1: construct the base A,B,C on the plane z=0
real a=5, b=4, c=3;
triple B=(0,0,0), C=(a,0,0);
// Abc is the projection of A on the segment BC
triple Abc=barycentric(B,C,O,1/(a^2+c^2-b^2),1/(a^2+b^2-c^2),0);
real bt=abs(Abc-B);
real hbc=sqrt(c*c-bt*bt);
triple A=Abc+hbc*dir(90,90);
draw(A--B--C--cycle,blue+1pt);
label("$A$",A,plain.S);
label("$B$",B,dir(150));
label("$C$",C,plain.NW);
//label("$A_{bc}$",Abc,plain.N,red);
//draw(A--Abc,red);
// Step 2: get the top point D
real at=6, bt=7, ct=8;
// H is the projection of D on the base ABC
// https://en.wikipedia.org/wiki/True-range_multilateration
real Hx=(bt^2-ct^2+a^2)/(2a);
real Hy=(bt^2-at^2+A.x^2+A.y^2-2A.x*Hx)/(2A.y);
real Dz=sqrt(bt^2-Hx^2-Hy^2);
triple H=(Hx,Hy,0);
triple D=(Hx,Hy,Dz);
draw(D--A^^D--B^^D--C,blue+1pt);
draw(D--H,red+dashed);
label("$D$",D,plain.N);
label("$H$",H,plain.E,red); dot(H,red);
// grid on XY-plane
limits((-2,-2,0),(7,5,0));
grid3(XYXgrid,step=1,.5gray+.5white);
draw(Label("$x$",EndPoint),O--8X,Arrow3());
draw(Label("$y$",EndPoint),O--6Y,Arrow3());
draw(Label("$z$",EndPoint),O--6Z,Arrow3());
write("H = ("+string(H.x)+","+string(H.y)+",0)");
write("DH = "+string(abs(H-D)));
旧答案这是欧几里得几何中一个著名的构造问题。在绘图时,我们可以使用几何构造,但最好使用计算方法。在一些计算方法中,我发现一种使用barycentric coordinate
更方便的方法,可以用于绘制二维和三维图形。
问题 1. 平面上的三角形: 在平面 Oxy 上作三角形 ABC,已知三角形的三条边 a=BC、b=CA、c=AB(假设三角形a + b > c
成立)
通常的方法是先取和B
,C
使得BC=a
,然后是以半径为圆心的圆和以半径为圆心的圆A
的两个交点之一,使用一些内置程序来查找两个圆的交点。在这里我采用计算方法, 使用B
c
C
b
path
barycentric coordinate
pair barycentric(pair A=(0,0), pair B=(0,0), real a=1, real b=0){
return (a*A+b*B)/(a+b);}
重写公式这是我的答案H
,得到A
BC
pair H=barycentric(B,C,1/(a^2+c^2-b^2),1/(a^2+b^2-c^2));
最后A
利用勾股定理得到直角三角形中的该点AHB
。
// http://asymptote.ualberta.ca/
pair barycentric(pair A=(0,0), pair B=(0,0), real a=1, real b=0){
return (a*A+b*B)/(a+b);}
// Application: construct a triangle knowing the lengths of 3 sides
unitsize(1cm);
real a=6, b=5, c=2.5;
pair B=(0,0), C=(a,0);
pair H=barycentric(B,C,1/(a^2+c^2-b^2),1/(a^2+b^2-c^2));
real bt=abs(H-B);
real h=sqrt(c*c-bt*bt);
pair A=H+h*dir(90);
draw(box(H,H+(.2,.2)),red);
draw(A--H,red);
draw(A--B--C--cycle);
label("$A$",A,plain.N);
label("$B$",B,plain.SW);
label("$C$",C,plain.SE);
label("$H$",H,plain.S);
问题 2. 空间上的三角形:在空间 Oxyz 中构造三角形 ABC,已知其三个长度 a=BC、b=CA、c=AB(前提是a + b > c
满足三角不等式)
这可以按照问题 1 的方式进行,只需进行适当的微小改动(参见下面问题 3 代码中的步骤 1)。
问题 3. 空间上的四面体:要在空间 Oxyz 上构造一个四面体,D.ABC
已知它的 6 个长度(3 个底边长度a=BC
、b=CA
、c=AB
;以及 3 个剩余长度at=DA
、bt=DB
、 )ct=DC
(前提是满足某些条件,参见这篇 2009 年 EMS 论文)。
我们使用barycentric coordinate
2 倍。首先在某个平面上构造三角形 ABC,例如。这是上面的问题 2。接下来,得到在底面上的z=0
投影。Heron 公式用于 的重心坐标(使用面积而不是边长)H
D
ABC
H
import three;
triple barycentric(triple A, triple B, triple C, real a, real b, real c){return (a*A+b*B+c*C)/(a+b+c);}
real Heron(real a, real b, real c){
real p=(a+b+c)/2;
return sqrt(p*(p-a)*(p-b)*(p-c));
}
D
然后利用勾股定理在直角三角形内找到所要的点DHA
。
完整代码(仍有一些错误!我正在寻找四面体高脚的重心坐标- 似乎是一个有趣而敏感的情况)
unitsize(1cm);
import three;
triple barycentric(triple A, triple B, triple C, real a, real b, real c){return (a*A+b*B+c*C)/(a+b+c);}
real Heron(real a, real b, real c){
real p=(a+b+c)/2;
return sqrt(p*(p-a)*(p-b)*(p-c));
}
currentprojection=orthographic((1,1.6,1),center=true,zoom=.95);
// Step 1: construct the base A,B,C on the plane z=0
real a=6, b=5, c=4;
triple B=(0,0,0), C=(a,0,0);
// Abc is the projection of A on the segment BC
triple Abc=barycentric(B,C,O,1/(a^2+c^2-b^2),1/(a^2+b^2-c^2),0);
real bt=abs(Abc-B);
real hbc=sqrt(c*c-bt*bt);
triple A=Abc+hbc*dir(90,90);
draw(A--Abc,red);
draw(A--B--C--cycle);
label("$A$",A,plain.S);
label("$B$",B,plain.E);
label("$C$",C,plain.W);
label("$A_{bc}$",Abc,plain.N,red);
// Step 2: get the top point D
real at=6, bt=7, ct=4;
// H is the projection of D on the base ABC
real Sdab=Heron(at,bt,c);
real Sdbc=Heron(bt,ct,a);
real Sdca=Heron(ct,at,b);
triple H=barycentric(A,B,C,1/(Sdab^2+Sdca^2-Sdbc^2),1/(Sdab^2+Sdbc^2-Sdca^2),1/(Sdca^2+Sdbc^2-Sdab^2));
real ha=abs(H-A);
real hd=sqrt(at*at-ha*ha);
triple D=H+hd*Z;
draw(D--A^^D--B^^D--C);
draw(D--H,blue);
label("$D$",D,plain.N);
label("$H$",H,plain.W,blue); dot(H);
PS1:为什么是 Asymptote 而不是 TikZ?这种绘图方式barycentric coordinate
可以用几种绘图语言编写。TikZ 确实有barycentric coordinate
;但它的计算能力很弱,Dimension too large
可能会出错,即使在 2D 中,当我尝试绘制三角形的欧拉线时也是如此)!Asymptote 具有更好的准确性,并且可用于 3D。
PS2:还有一种基于折纸的方法,在波利亚的一本书中有描述。我以后有空的时候会这样做。
答案3
这是一个两步方法,首先使用tkz-euclide
(图形)获得 S 点,然后使用简单的 Ti钾用四面体进行 Z 3d 绘图。
第一步(tkz-euclide
)
这里我求点 S 的水平投影 F 和四面体的高度 FS。我使用画法几何,特别是辅助倾斜视图。
代码:
\documentclass[border=2mm]{standalone}
\usepackage{tkz-euclide}
\begin{document}
\begin{tikzpicture}
% triangle ABC
\tkzDefPoint(0,0){A}
\tkzDefPoint(3,0){B}
\tkzInterCC[R](A,4cm)(B,5cm)
\tkzGetFirstPoint{C}
\tkzCompass[color=red,delta=10](A,C)
\tkzCompass[color=red,delta=10](B,C)
\tkzDrawPolygon(A,B,C)
% triangle ABS1
\tkzInterCC[R](A,6cm)(B,7cm)
\tkzGetSecondPoint{S1}
\tkzCompass[color=red,delta=10](A,S1)
\tkzCompass[color=red,delta=10](B,S1)
% triangle ACS2
\tkzInterCC[R](A,6cm)(C,8cm)
\tkzGetFirstPoint{S2}
\tkzCompass[color=red,delta=5](A,S2)
\tkzCompass[color=red,delta=5](B,S2)
\tkzDrawSegments[blue](B,S1 S1,A A,S2 S2,C)
% points D,E,F,G,H
\tkzDefPointBy[projection = onto A--B](S1)
\tkzGetPoint{D}
\tkzDrawLine[dashed,add= 2cm and 1cm](S1,D)
\tkzDefPointBy[projection = onto A--C](S2)
\tkzGetPoint{E}
\tkzDrawLine[dashed,add= 1cm and 1cm](S2,E)
\tkzInterLL(S1,D)(S2,E)
\tkzGetPoint{F}
\tkzInterLC(A,C)(E,S2)
\tkzGetFirstPoint{G}
\tkzInterLC(F,S1)(E,S2)
\tkzGetFirstPoint{H}
\tkzDrawLine[add=0 and 1cm](A,G)
\tkzDrawArc(E,S2)(G)
% draw right angles
\tkzMarkRightAngle(D,F,S2)
\tkzMarkRightAngle(A,E,S2)
% draw points
\tkzDrawPoints(A,B,C,E,S1,S2,F,G,H)
\tkzLabelPoints(A,B,C,E,F,G,H)
\tkzLabelPoint(S1){$S_1$}
\tkzLabelPoint(S2){$S_2$}
% lengths
\tkzGetPointCoord(F){f}
\tkzCalcLength[cm](F,H)\tkzGetLength{dFH}
\tkzLabelPoint(-5,5) {$F(\pgfmathprint{\fx},\pgfmathprint{\fy})$}
\tkzLabelPoint(-5,4.5){$h=\overline{FH}=\pgfmathprint{\dFH}$}
\end{tikzpicture}
\end{document}
第二步(钛钾Z)
现在我已经确定了 S,大约为 (-2/3,-3/2,5.77083)。所以剩下的只是选择视图并放置点:
\documentclass[border=2mm,tikz]{standalone}
\usetikzlibrary{3d} % not needed if we only draw the tetrahedron
\usetikzlibrary{perspective}
\begin{document}
\begin{tikzpicture}[3d view={30}{-25},line cap=round,line join=round]
% coordinates
\coordinate (A) at (0,0,0);
\coordinate (B) at (3,0,0);
\coordinate (C) at (0,4,0);
\coordinate (S) at (-2/3,-3/2,5.77083); % see above tkz-euclide code
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% this is only for showing where is everything %
\begin{scope}[canvas is xy plane at z=0]
\draw[gray] (-2,-2) grid (4,5);
\end{scope}
\coordinate (F) at (-2/3,-3/2,0);
\draw[blue,dashed] (F) -- (S);
\fill (F) circle (1pt) node [left] {$F$};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% lines
\draw[blue,thick,dashed] (A) -- (B);
\draw[blue,thick] (C) -- (A) -- (S) -- (C) -- (B) -- (S);
% points
\fill (A) circle (1pt) node [left] {$A$};
\fill (B) circle (1pt) node [right] {$B$};
\fill (C) circle (1pt) node [below] {$C$};
\fill (S) circle (1pt) node [above] {$S$};
\end{tikzpicture}
\end{document}