从这里是否有命令可以找到平面上某个点的投影坐标?,我得到了答案。我知道,calc 库已经更新,而且在 calc 更新到 CTAN 之前就已经更新了。我希望,这个等式有一个更简单的答案。
答案1
更新:使用一些进一步的发展实验3dtools 库。我希望这还不是这个故事的最终结论。
\documentclass[border=3mm,12pt,tikz]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{3dtools}
\tikzset{3d projection of point/.style args={(#1,#2,#3) on plane through (#4,#5,#6)
with normal (#7,#8,#9)}{
/utils/exec={\pgfmathsetmacro{\myprefactor}{(#7*(#1-#4)%
+#8*(#2-#5)+#9*(#3-#6))%
/(#7*#7+#8*#8+#9*#9)}
\pgfmathsetmacro{\myx}{#1-\myprefactor*#7}
\pgfmathsetmacro{\myy}{#2-\myprefactor*#8}
\pgfmathsetmacro{\myz}{#3-\myprefactor*#9}},
insert path={%
({\myx},{\myy},{\myz})}},% symbolic version
symbolic 3d projection of point/.style args={#1 on plane through #2
with normal #3}{insert path={let \p1=(#1),\p2=(#2),\p3=(#3) in
[3d projection of point/.expanded=\coord1 on plane through \coord2 with normal \coord3]}}}
\begin{document}
\tdplotsetmaincoords{70}{110}
\begin{tikzpicture}[tdplot_main_coords,scale=1.5]
\pgfmathsetmacro\a{4}
\pgfmathsetmacro\b{3}
\pgfmathsetmacro\c{4}
% define the coordinates (note: \coordinate (A) at (0,0,0) does *NOT* work)
\path (0,0,0) coordinate(A)
(\a,0,0) coordinate (B)
(0,\b,0) coordinate (C)
(0,0,\c) coordinate (S)
[overlay,3d coordinate={(n)=(C)-(B)x(S)-(B)}];
% do the projection
\path[symbolic 3d projection of point={A on plane through S with
normal n}] coordinate (H);
% draw various parts
\draw[dashed,thick] (A) -- (B) (A) -- (C) (S)--(A) --(H) ;
\draw[thick] (S) -- (B) -- (C) -- cycle;
\foreach \point/\position in {A/left,B/left,C/below,S/above,H/above}
{
\fill (\point) circle (1.5pt);
\node[\position=3pt] at (\point) {$\point$};
}
\end{tikzpicture}
\end{document}
这是一次升级,但可能不是这个不断发展的故事的最终定论。有了这里的解析器,你就可以使用符号坐标了。代码很长,因为它有几个定义,希望有一天能进入一个库。这些技巧是由Henri Menke 最近提交的并已被使用这里。遗憾的是,在此版本中,您不能将符号坐标与显式坐标混合使用。现在您可以使用符号坐标,例如
\path[symbolic 3d projection of point={A on plane through S with
normal n}] coordinate (H);
法线n
可以通过符号坐标计算得出。其公式为
n = (C-B) x (S-B)
计算如下
\lincomb(CB)=1*(C)+(-1)*(B);
\lincomb(SB)=1*(S)+(-1)*(B);
\vecprod(n)=(CB)x(SB);
也就是说,我们首先需要形成线性组合C-B
,S-B
然后计算它们的向量积。嵌套解析需要解析专家来查看这一点。
\documentclass[border=3mm,12pt,tikz]{standalone}
\usepackage{tikz-3dplot}
% allows us to do linear combinations
\def\lincomb#1=#2*#3+#4*#5;{%
\path[overlay] let \p1=#3,\p2=#5 in
({(#2)*(xcomp3\coord1)+(#4)*(xcomp3\coord2)},%
{(#2)*(ycomp3\coord1)+(#4)*(ycomp3\coord2)},%
{(#2)*(zcomp3\coord1)+(#4)*(zcomp3\coord2)}) coordinate #1;}
\def\vecprod#1=#2x#3;{%
\path[overlay] let \p1=#2,\p2=#3 in
({vpx({\coord1},{\coord2})},%
{vpy({\coord1},{\coord2})},%
{vpz({\coord1},{\coord2})}) coordinate #1;}
\pgfmathdeclarefunction{xcomp3}{3}{% x component of a 3-vector
\begingroup%
\pgfmathparse{#1}%
\pgfmathsmuggle\pgfmathresult\endgroup}
\pgfmathdeclarefunction{ycomp3}{3}{% y component of a 3-vector
\begingroup%
\pgfmathparse{#2}%
\pgfmathsmuggle\pgfmathresult\endgroup}
\pgfmathdeclarefunction{zcomp3}{3}{% z component of a 3-vector
\begingroup%
\pgfmathparse{#3}%
\pgfmathsmuggle\pgfmathresult\endgroup}
% vector product auxiliary functions
\newcommand{\vpauxx}[6]{(#2)*(#6)-(#3)*(#5)}
\newcommand{\vpauxy}[6]{(#4)*(#3)-(#1)*(#6)}
\newcommand{\vpauxz}[6]{(#1)*(#5)-(#2)*(#4)}
% vector product pgf functions
\pgfmathdeclarefunction{vpx}{2}{% x component of vector product
\begingroup%
\pgfmathparse{\vpauxx#1#2}%
\pgfmathsmuggle\pgfmathresult\endgroup}
\pgfmathdeclarefunction{vpy}{2}{% y component of vector product
\begingroup%
\pgfmathparse{\vpauxy#1#2}%
\pgfmathsmuggle\pgfmathresult\endgroup}
\pgfmathdeclarefunction{vpz}{2}{% z component of vector product
\begingroup%
\pgfmathparse{\vpauxz#1#2}%
\pgfmathsmuggle\pgfmathresult\endgroup}
% original version of projection (works with symbolic coordinates)
\tikzset{3d projection of point/.style args={(#1,#2,#3) on plane through (#4,#5,#6)
with normal (#7,#8,#9)}{
/utils/exec={\pgfmathsetmacro{\myprefactor}{(#7*(#1-#4)%
+#8*(#2-#5)+#9*(#3-#6))%
/(#7*#7+#8*#8+#9*#9)}
\pgfmathsetmacro{\myx}{#1-\myprefactor*#7}
\pgfmathsetmacro{\myy}{#2-\myprefactor*#8}
\pgfmathsetmacro{\myz}{#3-\myprefactor*#9}},
insert path={%
({\myx},{\myy},{\myz})}},% symbolic version
symbolic 3d projection of point/.style args={#1 on plane through #2
with normal #3}{insert path={let \p1=(#1),\p2=(#2),\p3=(#3) in
[3d projection of point/.expanded=\coord1 on plane through \coord2 with normal \coord3]}}}
\begin{document}
\tdplotsetmaincoords{70}{110}
\begin{tikzpicture}[tdplot_main_coords,scale=1.5]
\pgfmathsetmacro\a{4}
\pgfmathsetmacro\b{3}
\pgfmathsetmacro\c{4}
% define the coordinates (note: \coordinate (A) at (0,0,0) does *NOT* work)
\path (0,0,0) coordinate(A)
(\a,0,0) coordinate (B)
(0,\b,0) coordinate (C)
(0,0,\c) coordinate (S);
\lincomb(C-B)=1*(C)+(-1)*(B);
\lincomb(S-B)=1*(S)+(-1)*(B);
% compute the normal n
\vecprod(n)=(C-B)x(S-B);
% do the projection
\path[symbolic 3d projection of point={A on plane through S with
normal n}] coordinate (H);
% draw various parts
\draw[dashed,thick] (A) -- (B) (A) -- (C) (S)--(A) --(H) ;
\draw[thick] (S) -- (B) -- (C) -- cycle;
\foreach \point/\position in {A/left,B/left,C/below,S/above,H/above}
{
\fill (\point) circle (1.5pt);
\node[\position=3pt] at (\point) {$\point$};
}
\end{tikzpicture}
\end{document}
这些解析器还允许我们直接计算投影。我们必须从A
投影中A-S
减去n
,H = A - (((A-S).(n))/((n).(n))) * n
。这可以直接完成(当然会产生相同的输出)。
\documentclass[border=3mm,12pt,tikz]{standalone}
\usepackage{tikz-3dplot}
% allows us to do linear combinations
\def\lincomb#1=#2*#3+#4*#5;{%
\path[overlay] let \p1=#3,\p2=#5 in
({(#2)*(xcomp3\coord1)+(#4)*(xcomp3\coord2)},%
{(#2)*(ycomp3\coord1)+(#4)*(ycomp3\coord2)},%
{(#2)*(zcomp3\coord1)+(#4)*(zcomp3\coord2)}) coordinate #1;}
% vector product
\def\vecprod#1=#2x#3;{%
\path[overlay] let \p1=#2,\p2=#3 in
({vpx({\coord1},{\coord2})},%
{vpy({\coord1},{\coord2})},%
{vpz({\coord1},{\coord2})}) coordinate #1;}
% scalar product
\makeatletter
\def\scalprod#1=#2.#3;{%
\path[overlay] let \p1=#2,\p2=#3 in
\pgfextra{\pgfmathsetmacro\pgfutil@tmpa{scalarproduct({\coord1},{\coord2})}
\xdef\pgfutil@tmpa{\pgfutil@tmpa}};%
\edef#1{\pgfutil@tmpa}}%
\makeatother
\newcommand{\spaux}[6]{(#1)*(#4)+(#2)*(#5)+(#3)*(#6)}
\pgfmathdeclarefunction{scalarproduct}{2}{% scalar product of two 3-vectors
\begingroup%
\pgfmathparse{\spaux#1#2}%
\pgfmathsmuggle\pgfmathresult\endgroup}
% projections
\pgfmathdeclarefunction{xcomp3}{3}{% x component of a 3-vector
\begingroup%
\pgfmathparse{#1}%
\pgfmathsmuggle\pgfmathresult\endgroup}
\pgfmathdeclarefunction{ycomp3}{3}{% y component of a 3-vector
\begingroup%
\pgfmathparse{#2}%
\pgfmathsmuggle\pgfmathresult\endgroup}
\pgfmathdeclarefunction{zcomp3}{3}{% z component of a 3-vector
\begingroup%
\pgfmathparse{#3}%
\pgfmathsmuggle\pgfmathresult\endgroup}
% vector product auxiliary functions
\newcommand{\vpauxx}[6]{(#2)*(#6)-(#3)*(#5)}
\newcommand{\vpauxy}[6]{(#4)*(#3)-(#1)*(#6)}
\newcommand{\vpauxz}[6]{(#1)*(#5)-(#2)*(#4)}
% vector product pgf functions
\pgfmathdeclarefunction{vpx}{2}{% x component of vector product
\begingroup%
\pgfmathparse{\vpauxx#1#2}%
\pgfmathsmuggle\pgfmathresult\endgroup}
\pgfmathdeclarefunction{vpy}{2}{% y component of vector product
\begingroup%
\pgfmathparse{\vpauxy#1#2}%
\pgfmathsmuggle\pgfmathresult\endgroup}
\pgfmathdeclarefunction{vpz}{2}{% z component of vector product
\begingroup%
\pgfmathparse{\vpauxz#1#2}%
\pgfmathsmuggle\pgfmathresult\endgroup}
\begin{document}
\tdplotsetmaincoords{70}{110}
\begin{tikzpicture}[tdplot_main_coords,scale=1.5]
\pgfmathsetmacro\a{4}
\pgfmathsetmacro\b{3}
\pgfmathsetmacro\c{4}
% define the coordinates (note: \coordinate (A) at (0,0,0) does *NOT* work)
\path (0,0,0) coordinate(A)
(\a,0,0) coordinate (B)
(0,\b,0) coordinate (C)
(0,0,\c) coordinate (S);
\lincomb(C-B)=1*(C)+(-1)*(B);
\lincomb(S-B)=1*(S)+(-1)*(B);
\lincomb(A-S)=1*(A)+(-1)*(S);
% compute the normal n
\vecprod(n)=(C-B)x(S-B);
% projection of (A-S) on n
\scalprod\mysp=(A-S).(n);
% square of n
\scalprod\myln=(n).(n);
% H = A - (((A-S).(n))/((n).(n))) * n
\lincomb(H)=1*(A)+{(-1*(\mysp)/\myln)}*(n);
% draw various parts
\draw[dashed,thick] (A) -- (B) (A) -- (C) (S)--(A) --(H) ;
\draw[thick] (S) -- (B) -- (C) -- cycle;
\foreach \point/\position in {A/left,B/left,C/below,S/above,H/above}
{
\fill (\point) circle (1.5pt);
\node[\position=3pt] at (\point) {$\point$};
}
\end{tikzpicture}
\end{document}
答案2
这可以通过Asymptoteplaneproject
模块的命令轻松完成。three
// http://asymptote.ualberta.ca/
unitsize(1cm);
import three;
currentprojection=orthographic(2,4,1,zoom=.8);
triple A=(3,0,0), B=(0,6,0), C=(0,0,4);
path3 base=A--B--C--cycle;
triple H=planeproject(base,normal(base))*O;
draw(O--A^^O--B^^O--C,dashed);
draw(O--H,red);
draw(base);
dot("$A$",A,W);
dot("$B$",B,E);
dot("$C$",C,N);
dot("$O$",O,NE);
dot("$H$",H,SW,red);