如何从点X在接地平面OAB上画一条垂直于AB的线?
是否有一个简单的机制或者我必须使用像 tikz-3d 这样的东西?
\documentclass[margin=5pt, tikz]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\pgfmathsetmacro{\a}{5}%
\pgfmathsetmacro{\b}{5}%
\begin{tikzpicture}[font=\footnotesize,]
\coordinate[label=left:$O$] (O) at (0,0,0);
\coordinate[label=below:$B$] (B) at (\b,0,0);
\coordinate[label=below:$A$] (A) at (0,0,\a);
\coordinate[label=below:$X$] (X) at ($(A)!0.4!(B)$);
\draw[] (A) -- (B);
\draw[help lines] (O) -- (A);
\draw[help lines] (O) -- (B);
\draw[red] (X) -- ($(X)!1 cm!-90:(A)$);
\begin{scope}[-latex, shift={(-0.5*\a,0.5*\a,0)}]
\foreach \P/\s/\Pos in {(1,0,0)/x/below, (0,1,0)/y/left, (0,0,2)/z/right}
\draw[] (0,0,0) -- \P node[\Pos, pos=0.9,inner sep=2pt]{$\s$};
\end{scope}
\end{tikzpicture}
\end{document}
答案1
设u = cross(OA,OB)
和v = (B) - (A)
,则求得直线的方向向量cross(u,v)
。计算可得cross(u,v)= {-a^2 b, 0, -a b^2}
。我用{a,0,b}
作为直线的方向向量 。然后写出过 和 的直线方程X
有方向向量 ,就得到这条直线上的点Y = (\b/4 -\a,0,3*\a/4-\b)
。过两点X
和 的直线 。我加上点在线 上的Y
投影点。注意平行于。H
O
AB
XY
OH
\documentclass[margin=5pt, tikz]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\pgfmathsetmacro{\a}{5}%
\pgfmathsetmacro{\b}{5}%
\begin{tikzpicture}[font=\footnotesize,]
\coordinate[label=left:$O$] (O) at (0,0,0);
\coordinate[label=below:$B$] (B) at (\b,0,0);
\coordinate[label=below:$A$] (A) at (0,0,\a);
\coordinate[label=below:$X$] (X) at (\b/4,0,3*\a/4);
\coordinate[label=below:$Y$] (Y) at (\b/4 -\a,0,3*\a/4-\b);
\coordinate[label=below:$H$] (H) at ({\a*\a*\b/(\a*\a+\b*\b)}, 0, {\a*\b*\b/(\a*\a+\b*\b)});
\draw[] (A) -- (B);
\draw[help lines] (O) -- (A);
\draw[help lines] (O) -- (B);
\draw[red] (Y) -- (X) ;
\draw[blue] (O) -- (H) ;
\begin{scope}[-latex, shift={(-0.5*\a,0.5*\a,0)}]
\foreach \P/\s/\Pos in {(1,0,0)/x/below, (0,1,0)/y/left, (0,0,2)/z/right}
\draw[] (0,0,0) -- \P node[\Pos, pos=0.9,inner sep=2pt]{$\s$};
\end{scope}
\end{tikzpicture}
\end{document}
在上面的代码中,点的坐标H
是通过以下方式找到的枫软。基于 这个答案,你不需要找到它。
\documentclass[tikz,border=1 mm,12pt]{standalone}
\usepackage{fouriernc}
\usetikzlibrary{3dtools}
\tikzset{intersection of line trough/.code args={#1 and #2 with plane
containing #3 and normal #4}{%
\pgfmathsetmacro{\ltest}{abs(TD("#2o#4")-TD("#1o#4"))}%
\ifdim\ltest pt<0.01pt
\message{Plane and line are parallel!^^J}
\pgfmathsetmacro{\myd}{0}
\else
\pgfmathsetmacro{\myd}{(TD("#3o#4")-TD("#1o#4"))/(TD("#2o#4")-TD("#1o#4"))}%
\fi
\pgfmathsetmacro{\myP}{TD("#1+\myd*#2-\myd*#1")}%
\pgfkeysalso{insert path={%
(\myP)
}}
}}
\begin{document}
\pgfmathsetmacro{\a}{5}%
\pgfmathsetmacro{\b}{5}%
\begin{tikzpicture}
\path
(0,0,0) coordinate (O)
(\b,0,0) coordinate (B)
(0,0,\a) coordinate (A)
({\a*\a*\b/(\a*\a+\b*\b)}, 0, {\a*\b*\b/(\a*\a+\b*\b)}) coordinate (H')
[
3d coordinate={(myn)=(A)-(B)}
];
\path[intersection of line trough={(A) and (B) with plane containing
(O) and normal (myn)}]
coordinate (H);
\foreach \p in {A,B,O,H}
\draw[fill=black] (\p) circle (1.5pt);
\foreach \p/\g in {A/135,B/90,O/180}
\path (\p)+(\g:3mm) node{$\p$};
\draw (A) -- (B) -- (O) -- cycle;
\path[red] foreach \X in {H}
{(\X) node[above] {$\X$} (\X') node[below] {$\X'$}};
\draw (O) -- (H);
\end{tikzpicture}
\end{document}
和3d工具
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{3dtools,intersections,calc}
\begin{document}
\begin{tikzpicture}[3d/install view={phi=110,psi=0,theta=60},
dot/.style={circle,inner sep=0pt,
minimum size=2pt,fill}]
\draw[every coordinate node/.append style={dot}]
(2,1,2) coordinate[label=above:{$A$}] (A) --
(1,2,1) coordinate[label=below:{$B$}] (B) --
(2,0,0) coordinate[label=below:{$C$}] (C) -- cycle
(0,0,0) coordinate[label=above:{$O$}] (O)
(3,-2,1) coordinate[label=below:{$D$}] (D);
\path[3d/plane through={(A) and (B) and (C) named pABC},
3d/plane with normal={(1,1,1) through (C) named ptwo},
3d/line through={(A) and (B) named lAB},
3d/line through={(O) and (D) named lOD}];
% project point on plane
\path[3d/project={(O) on pABC}] coordinate (O');
% project point on line
\path[3d/project={(C) on lAB}] coordinate (C');
% intersection of plane and line
\path[3d/intersection of={lOD with pABC}] coordinate (I);
\draw[dashed] (C) -- (C')
coordinate[dot,label=above right:{$C'=\pgfmathparse{TD("(C')")}%
(\pgfmathprintvector\pgfmathresult)^T$}];
\path (O') coordinate[dot,label=right:{$O'=\pgfmathparse{TD("(O')")}%
(\pgfmathprintvector\pgfmathresult)^T$}];
\path (I) coordinate[dot,label=above:{$I=\pgfmathparse{TD("(I)")}%
(\pgfmathprintvector\pgfmathresult)^T
$}];
\end{tikzpicture}
\end{document}
答案2
正如@Henri Menke 上面提到的,TikZ 并不是适合正交投影 3D 的工具。
对于(3D)渐近线,很容易使用乘积得到从一点P
到线段的垂线的脚,如下所示(从点积的定义中可以很容易地得出)AB
dot
triple foot(triple P,triple A, triple B){
real s=dot(P-A,unit(B-A));
return A+s*unit(B-A);
}
所以代码很自然!
// http://asymptote.ualberta.ca/
unitsize(1cm);
import three;
// The foot of the perpendicular from P to line AB:
triple foot(triple P,triple A, triple B){
real s=dot(P-A,unit(B-A));
return A+s*unit(B-A);
}
currentprojection=orthographic(2,1,1,zoom=.95,center=true);
triple A=(4,1,-1), B=(-2,5,1), C=(-1,-2.5,2);
triple H=foot(C,A,B);
draw(C--H,red+.8pt);
triple P=.8A+.2B;
triple Q=C+P-H;
draw(P--Q,blue+.8pt);
draw(surface(A--B--C--cycle),yellow+opacity(.8));
draw(A--B--C--cycle);
label("$A$",A,S);
label("$B$",B,E);
label("$C$",C,W);
label("$H$",H,SE);
label("$P$",P,SE);
label("$Q$",Q,W);
draw(Label("$x$",EndPoint),O--5X,Arrow3);
draw(Label("$y$",EndPoint),O--5Y,Arrow3);
draw(Label("$z$",EndPoint),O--4Z,Arrow3);
// to mark right angles
path3 Rmark(triple A, triple B, triple C, real size=.4){
triple Ba=B+size*unit(A-B);
triple Bc=B+size*unit(C-B);
triple Bt=Ba+Bc-B;
return Ba--Bt--Bc;
}
draw(Rmark(C,H,B),red);
draw(Rmark(Q,P,B,.5),blue);
您可能需要检查垂直度。