我怎样才能画出平面和直线的交点?

我怎样才能画出平面和直线的交点?

假设 SOAB 是一个金字塔,OAB是一个等边三角形,SO垂直于平面OAB。通过O并垂直于线的平面在和处与SB相交。我试过了SBMSAN

\documentclass[border=3mm,12pt,tikz]{standalone}
\usepackage{fouriernc}
\usepackage{tikz,tikz-3dplot} 
\tikzset{projection of point/.style args={(#1,#2,#3) on line through (#4,#5,#6)
        and (#7,#8,#9)}{%
        /utils/exec=\pgfmathsetmacro{\myprefactor}{((#1-#4)*(#7-#4)+(#2-#5)*(#8-#5)+(#3-#6)*(#9-#6))/((#7-#4)*(#7-#4)+(#8-#5)*(#8-#5)+(#9-#6)*(#9-#6))},
        insert path={%
            ({#4+\myprefactor*(#7-#4)},{#5+\myprefactor*(#8-#5)},{#6+\myprefactor*(#9-#6)})}
}}
\begin{document}
    \tdplotsetmaincoords{60}{70}
    \begin{tikzpicture}[tdplot_main_coords]
\pgfmathsetmacro\a{4}
\pgfmathsetmacro\h{5}
        \path
        coordinate(O) at (0,0,0)
        coordinate (A) at (\a,0,0)
        coordinate (B) at   (\a/2,{\a*sqrt(3)/2},0) 
         coordinate (S) at (0,0,\h) 
;            
        \path[projection of point={(0,0,0) on line through (\a/2,{\a*sqrt(3)/2},0) and (0,0,\h)}]
coordinate  (M);    
    \draw (S) -- (O) -- (A) -- (B) -- cycle (S) -- (A); 
\draw[dashed] (O) -- (B) (O) -- (M);        
\foreach \point/\position in {A/below,B/right,O/below,S/above,M/above}
        {\fill (\point) circle (1.5pt);
            \node[\position=1.5pt] at (\point) {$\point$};
        }
    \end{tikzpicture}
\end{document} 

在此处输入图片描述

我无法绘制该点N。我该如何绘制它?

答案1

第一种方式该点的坐标Ncoordinate (N) at ({2*\h*\h*\a/(\a*\a + 2*\h*\h)}, 0,{\a*\a*\h/(\a*\a + 2*\h*\h)} )

 \documentclass[border=3mm,12pt,tikz]{standalone}
\usepackage{fouriernc}
\usepackage{tikz,tikz-3dplot} 
\tikzset{projection of point/.style args={(#1,#2,#3) on line through (#4,#5,#6)
        and (#7,#8,#9)}{%
        /utils/exec=\pgfmathsetmacro{\myprefactor}{((#1-#4)*(#7-#4)+(#2-#5)*(#8-#5)+(#3-#6)*(#9-#6))/((#7-#4)*(#7-#4)+(#8-#5)*(#8-#5)+(#9-#6)*(#9-#6))},
        insert path={%
            ({#4+\myprefactor*(#7-#4)},{#5+\myprefactor*(#8-#5)},{#6+\myprefactor*(#9-#6)})}
}}
\begin{document}
    \tdplotsetmaincoords{60}{70}
    \begin{tikzpicture}[tdplot_main_coords]
\pgfmathsetmacro\a{4}
\pgfmathsetmacro\h{5}
        \path
        coordinate(O) at (0,0,0)
        coordinate (A) at (\a,0,0)
        coordinate (B) at   (\a/2,{\a*sqrt(3)/2},0) 
         coordinate (S) at (0,0,\h) 
         coordinate  (N) at ({2*\h*\h*\a/(\a*\a + 2*\h*\h)}, 0,{\a*\a*\h/(\a*\a + 2*\h*\h)} ) 
;            
        \path[projection of point={(0,0,0) on line through (\a/2,{\a*sqrt(3)/2},0) and (0,0,\h)}]
coordinate  (M);    
    \draw (S) -- (O) -- (A) -- (B) -- cycle (S) -- (A); 
\draw[dashed] (O) -- (B) (O) -- (M);        
\foreach \point/\position in {A/below,B/right,O/below,S/above,M/above,N/left}
        {\fill (\point) circle (1.5pt);
            \node[\position=1.5pt] at (\point) {$\point$};
        }
    \end{tikzpicture}
\end{document} 

在此处输入图片描述

第二种方式

计算两点的坐标MN

\documentclass[border=3mm,12pt,tikz]{standalone}
\usepackage{tikz-3dplot} 
\begin{document}
    \tdplotsetmaincoords{60}{70}
\begin{tikzpicture}[tdplot_main_coords]
    \pgfmathsetmacro\a{4}
    \pgfmathsetmacro\h{5}
    \path
    coordinate(O) at (0,0,0)
    coordinate (A) at (\a,0,0)
    coordinate (B) at   (\a/2,{\a*sqrt(3)/2},0) 
    coordinate (S) at (0,0,\h) 
    coordinate  (N) at ({2*\h*\h*\a/(\a*\a + 2*\h*\h)}, 0,{\a*\a*\h/(\a*\a + 2*\h*\h)} ) 
    coordinate  (M) at  ({\h*\h*\a/(2*\a*\a + 2*\h*\h)}, {\h*\h*\a*sqrt(3)/(2*\a*\a + 2*\h*\h)},{\a*\a*\h/(\a*\a + \h*\h)} ) 
    ;   
    \draw (S) -- (O) -- (A) -- (B) -- cycle (S) -- (A); 
    \draw[dashed] (O) -- (B) (O) -- (M);        
    \foreach \point/\position in {A/below,B/right,O/below,S/above,N/right,M/right}
    {\fill (\point) circle (1.5pt);
        \node[\position=1.5pt] at (\point) {$\point$};
    }
\end{tikzpicture}
\end{document} 

第三条道路利用3dtool过点O且垂直于直线的平面SB取向量SB为法向量,求得两点MN

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{3dtools,calc}

\begin{document}
        \begin{tikzpicture}[line cap=round,line join=round,c/.style={circle,fill,inner sep=1pt},
        3d/install view={phi=70,theta=65},declare function={a=4;h=5;}]
        \path 
        (0,0,0) coordinate (O)  
        (a,0,0) coordinate (A)
        (a/2,{a*sqrt(3)/2},0) coordinate (B)  
        (0,0,h) coordinate (S)
        [3d coordinate={(n)=(S)-(B)}]
        ;
        \path[3d/plane with normal={(n) through (O) named p},
        3d/line through={(S) and (A) named lSA},
        3d/line through={(S) and (B) named lSB}];

    \path[3d/intersection of={lSA with p}] coordinate (N);  
    \path[3d/intersection of={lSB with p}] coordinate (M);
\draw[3d/visible] (S) -- (O) -- (A) -- (B)--cycle (S) -- (A);
\draw[3d/hidden] (O) -- (B) (O) -- (M);
    
\path foreach \p/\g in {S/90,A/-90,B/-90,O/-90,M/0,N/180}
{(\p)node[c]{}+(\g:2.5mm) node{$\p$}};      
    \end{tikzpicture}
\end{document}

在此处输入图片描述

或者你可以尝试

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{3dtools,calc}
\begin{document}
\foreach \Angle in {5,10,...,355}
    {\begin{tikzpicture}[line cap=round,line join=round,c/.style={circle,fill,inner sep=1pt},
        3d/install view={phi=\Angle,theta=65},declare function={a=4;h=5;},same bounding box=A]
        \path 
        (0,0,0) coordinate (O)  
        (a,0,0) coordinate (A)
        (a/2,{a*sqrt(3)/2},0) coordinate (B)  
        (0,0,h) coordinate (S)
        [3d coordinate={(n)=(S)-(B)}]
        ;
        \path[3d/plane with normal={(n) through (O) named p},
        3d/line through={(S) and (A) named lSA},
        3d/line through={(S) and (B) named lSB}];

    \path[3d/intersection of={lSA with p}] coordinate (N);  
    
        \path[3d/intersection of={lSB with p}] coordinate (M);

    \pgfmathsetmacro{\mybarycenter}{barycenter("(S),(O),(B),(A)")}
\path (\mybarycenter) coordinate (I);   
    \tikzset{3d/polyhedron/.cd,O={(I)},fore/.append style={fill=none},
    back/.append style={3d/hidden},
    draw face with corners={{(S)},{(O)},{(N)}},
    draw face with corners={{(O)},{(A)},{(N)}},
    draw face with corners={{(S)},{(M)},{(N)}},
    draw face with corners={{(A)},{(B)},{(M)},{(N)}},
    draw face with corners={{(A)},{(B)},{(O)}},
    draw face with corners={{(S)},{(M)},{(O)}},
    draw  face with corners={{(B)},{(M)},{(O)}}}    
\path foreach \p/\g in {S/90,A/-90,B/-90,O/-90,M/0,N/180}
{(\p)node[c]{}+(\g:2.5mm) node{$\p$}};      
    \end{tikzpicture}}
\end{document}

在此处输入图片描述

绘制点 N 的一种方法E是线段的中点OBI是两条线段SE和的交点OM,且IN平行于AE

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{3dtools,calc}
\begin{document}
        \begin{tikzpicture}[line cap=round,line join=round,c/.style={circle,fill,inner sep=1pt},
            3d/install view={phi=75,theta=65},declare function={a=4;h=5;}]
            \path 
            (0,0,0) coordinate (O)  
            (a,0,0) coordinate (A)
            (a/2,{a*sqrt(3)/2},0) coordinate (B)  
            (0,0,h) coordinate (S)
        [3d coordinate={(E)=0.5*(O)+0.5*(B) }];
            \path[
            3d/line through={(S) and (A) named lSA},
            3d/line through={(S) and (B) named lSB},
            3d/line through={(S) and (E) named lSE}];
        \path [3d/project={(O) on lSB}] coordinate (M);
    \path [3d/line through={(O) and (M) named lOM}];
    
    \path[3d/intersection of={lOM with lSE}] coordinate (I);
    
    \path[3d/line with direction={(A) - (E) through (I) named lIN}];
    
    \path[3d/intersection of={lIN with lSA}] coordinate (N);
            
    \draw[3d/visible] (S) --(O) -- (A) -- (B) --cycle (S) -- (A) (O) -- (N) -- (M);     
\draw[3d/hidden] (O) -- (B) (O) -- (M) (S) -- (E) (A) -- (E) (I) -- (N);        
            \path foreach \p/\g in {S/90,A/-90,B/-90,O/-150,M/60,E/-90,I/180,N/-30}
            {(\p)node[c]{}+(\g:2.5mm) node{$\p$}};      
    \end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

模块中有一个内置函数数学渐近线

real intersect(triple P, triple Q, triple n, triple Z)

返回线段PQ的延长线与垂直于n且过Z的平面的相交时间。

此时平面O与法线 相交n=BS,所以交点为tM=intersect(S,B,n,O),则线段SB 与该平面的交点M为 ,M=point(S--B,tM)另一交点 同理N

在此处输入图片描述

// http://asymptote.ualberta.ca/
unitsize(1cm);
import math; // for intersection of a line and a plane
import three;
real a=4,h=5;
triple O=(0,0,0),A=(a,0,0),B=(a/2,a*sqrt(3)/2,0),S=(0,0,h);
triple n=S-B;
real tM=intersect(S,B,n,O);
real tN=intersect(S,A,n,O);
triple M=point(S--B,tM);dot(M,red);
triple N=point(S--A,tN);dot(N,red);
draw(O--S^^O--A^^O--B,dashed);
draw(O--M^^O--N,dashed+red);
draw(S--A--B--cycle);
draw(M--N,red);

label("$A$",A,W);
label("$B$",B,E);
//label("$O$",O);
label("$S$",S,plain.N);
label("$M$",M,E,red);
label("$N$",N,W,red);

currentprojection可以通过设置和来设置视图和灯光currentlight,然后手动进行dashed相应更改。该选项opacity应用于平面部分OMN

在此处输入图片描述

unitsize(1cm);
import math; // for intersection of a line and a plane
import three;
currentprojection=orthographic(1,-1,.5,zoom=.9);
currentlight=Headlamp;
real a=4,h=3.5;
triple O=(0,0,0),A=(a,0,0),B=(a/2,a*sqrt(3)/2,0),S=(0,0,h);
triple n=S-B;
real tM=intersect(S,B,n,O);
real tN=intersect(S,A,n,O);
triple M=point(S--B,tM);dot(M,red);
triple N=point(S--A,tN);dot(N,red);
draw(surface(O--M--N--cycle),.2red+.8white+opacity(.2));
draw(O--B,dashed);
draw(O--M,dashed+red);
draw(S--A--B--cycle^^S--O--A);
draw(M--N--O,red);

label("$A$",A,plain.S);
label("$B$",B,E);
label("$O$",O,W);
label("$S$",S,plain.N);
label("$M$",M,NE);
label("$N$",N,E);

答案3

使用 Asymptote 进行编译http://asymptote.ualberta.ca/

关于隐藏或可见线的问题渐近线这是一个例子,https://asy.marris.fr/asymptote/Solides/index.html#fig_py05_261011_pyramide

现在,恕我直言,我们仍然手动绘制虚线。

我想,在未来(也许渐近线3.0 或更高版本),我们会针对此问题做出实现(自动隐藏线条)。

// settings.render=7;
import three;

size(5cm,0);
currentprojection=orthographic(1,-0.8,0.8);

// Project P onto plane through point O with normal n.
triple pointproject(triple P, triple O=O, triple n)
{
  return planeproject(n,O)*P;
}

// Project P onto plane through 3 points A,B,C
triple pointproject(triple P, triple A, triple B, triple C)
{
  return pointproject(P,A,unit(cross(B-A,C-A)));
}

// Project P onto line through 2 points A,B
triple pointproject(triple P, triple A, triple B)
{
  triple normalPAB=normal(P--A--B--cycle);
  triple thirdpoint=shift(planeproject(P--A--B--cycle)*normalPAB-normalPAB)*A;
  return pointproject(P,A,B,thirdpoint);
}

triple extension(triple P, triple Q, triple p, triple q) // uncompleted
{
  triple PQ=Q-P;
  triple pq=q-p;
  real a=PQ.x,b=PQ.y,c=PQ.z;
  real a_=pq.x,b_=pq.y,c_=pq.z;
  /*
        x=P.x+a*t,           x'=p.x+a_*u,
   (PQ) y=P.y+b*t,  and (pq) y'=p.y+b_*u,
        z=P.z+c*t            z'=p.z+c_*u
  Solving system of equations
  x=P.x+a*t,       x'=p.x+a_*u,
  y=P.y+b*t,  and  y'=p.y+b_*u,
  */
  real[][] A={{a,-a_},{b,-b_}};
  real[] B={p.x-P.x,p.y-P.y};
  real[] result=solve(A,B);
  return (P.x+a*result[0],P.y+b*result[0],P.z+c*result[0]);
}

real AngleBetweenTwoLines(triple P, triple Q, triple p, triple q)
{
  triple PQ=Q-P;
  triple pq=q-p;
  real a=dot(PQ,pq),b=abs(PQ),c=abs(pq);
  return aCos(abs(a)/(b*c));
}

real a=4, h=5;
triple A=(a,0,0),B=(a/2,a*sqrt(3)/2,0),S=(0,0,h);

draw(S--O^^S--A^^S--B);
draw(O--A--B);
draw(O--B,dashed);

dot("$S$",S,dir(90));
dot("$O$",O,dir(-135));
dot("$A$",A,dir(-90));
dot("$B$",B,dir(0));

triple M=pointproject(O,S,B);
triple E=(A+B)/2;
triple K=pointproject(O,S,E);
triple N=extension(S,A,M,K);

dot("$M$",M,dir(30));
dot("$E$",E,dir(-10));
dot("$K$",K,dir(-10));
dot("$N$",N,dir(-10));

draw(O--M,dashed);
draw(O--E,dashed);
draw(O--K,dashed);
draw(S--E^^M--N--O);

write(AngleBetweenTwoLines(S,B,O,N)); // Outputs: 90

在此处输入图片描述

关于平面与直线的交点,另请参阅这个例子

命令是 triple[] intersectionpoints(path3 p, surface s, real fuzz=-1);

相关内容