我有一个直角三角形 △ABC其直角为C以及斜边的高度。我有代码应该在C和海拔高度脚下。类似的命令显示略有不同的直角标记。海拔高度脚下的那个是正确的。C不垂直于侧面公元前。我画了一条绿线段来说明这一点。
\documentclass{amsart}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{tikz}
\usetikzlibrary{calc,intersections}
\usepackage{mathtools}
\begin{document}
\begin{tikzpicture}
%A right triangle is drawn.
\path (0,0) coordinate (A) ({(1/4)*16},0) coordinate (B) ({(1/4)*12},{(1/4)*(4*sqrt(3))}) coordinate (C);
\draw (A) -- (B) -- (C) -- cycle;
%The vertices are labeled.
\node[anchor=north, inner sep=0, font=\footnotesize] at ($(A) +(0,-0.15)$){$A$};
\node[anchor=north, inner sep=0, font=\footnotesize] at ($(B) +(0,-0.15)$){$B$};
\node[anchor=south, inner sep=0, font=\footnotesize] at ($(C) +(0,0.15)$){$C$};
%A right-angle mark is drawn at C.
\coordinate (U) at ($(C)!5mm!45:(A)$);
\draw ($(A)!(U)!(C)$) -- (U) -- ($(B)!(U)!(C)$);
\draw[green] let \p1=($(B)-(C)$), \n1={atan(\y1/\x1)} in (U) -- ($(U) +({\n1+180}:0.5)$);
\draw[fill=green] ($(A)!(U)!(C)$) circle (1pt);
%The foot of the altitude is labeled F.
\coordinate (F) at ({(1/4)*(12)},0);
\draw[dashed] (F) -- (C);
%A right-angle mark is drawn at F.
\coordinate (V) at ($(F)!3.25mm!-45:(A)$);
\draw ($(A)!(V)!(B)$) -- (V) -- ($(C)!(V)!(F)$);
\end{tikzpicture}
\end{document}
答案1
正如 Mark Wibrow 在这个答案\pgfpointnormalised
可以修正的定义以获得更好的精度。
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc, spy}
% use the Mark Wibrow's correction
\makeatletter
\def\pgfpointnormalised#1{%
\pgf@process{#1}%
\pgfmathatantwo{\the\pgf@y}{\the\pgf@x}%
\let\pgf@tmp=\pgfmathresult%
\pgfmathcos@{\pgf@tmp}\pgf@x=\pgfmathresult pt\relax%
\pgfmathsin@{\pgf@tmp}\pgf@y=\pgfmathresult pt\relax%
}
\makeatother
\begin{document}
\begin{tikzpicture}[spy using outlines={circle, magnification=7, size=17mm, connect spies}]
%A right triangle is drawn.
\path (0,0) coordinate (A) ({(1/4)*16},0) coordinate (B) ({(1/4)*12},{(1/4)*(4*sqrt(3))}) coordinate (C);
\draw (A) -- (B) -- (C) -- cycle;
%The vertices are labeled.
\node[anchor=north, inner sep=0, font=\footnotesize] at ($(A) +(0,-0.15)$){$A$};
\node[anchor=north, inner sep=0, font=\footnotesize] at ($(B) +(0,-0.15)$){$B$};
\node[anchor=south, inner sep=0, font=\footnotesize] at ($(C) +(0,0.15)$){$C$};
%A right-angle mark is drawn at C.
\coordinate (U) at ($(C)!5mm!45:(A)$);
\draw ($(A)!(U)!(C)$) -- (U) -- ($(B)!(U)!(C)$);
\draw[green] let \p1=($(B)-(C)$), \n1={atan(\y1/\x1)} in (U) -- ($(U) +({\n1+180}:0.5)$);
\draw[fill=green] ($(A)!(U)!(C)$) circle (1pt);
%The foot of the altitude is labeled F.
\coordinate (F) at ({(1/4)*(12)},0);
\draw[dashed] (F) -- (C);
%A right-angle mark is drawn at F.
\coordinate (V) at ($(F)!3.25mm!-45:(A)$);
\draw ($(A)!(V)!(B)$) -- (V) -- ($(C)!(V)!(F)$);
\spy[red] on (2.7,1.5) in node at (1,1.7);
\end{tikzpicture}
\end{document}
答案2
投影的计算涉及\pgfpointnormalised{⟨point⟩}
,记录如下
此命令返回 的标准版本
⟨point⟩
,即指向 方向的长度为 1pt 的向量⟨point⟩
。如果⟨point⟩
是 0 向量或极短,则返回指向上方的长度为 1pt 的向量。此命令不是通过计算向量的长度来实现的,而是通过计算向量的角度然后使用(等同于)命令来实现的\pgfpointpolar
。这确保了点的长度确实为 1pt,但不能保证向量精确指向 方向,⟨point⟩
因为极坐标表的精确度只有 1 度。通常,这不是问题。
所以这不是精度问题,而是算法问题特征。特别是,包括 fpu-engine 没有必要有帮助。
只需重新定义即可重写计算\tikz@cc@after@project
,一劳永逸地解决问题。
\documentclass{amsart}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{tikz}
\usetikzlibrary{calc,intersections}
\usepackage{mathtools}
\makeatletter
\newdimen\pgf@xd
\newdimen\pgf@yd
\def\tikz@cc@after@project#1{%
\pgf@process{#1}%
% Ok, now we need to project (xc,yc) on the line (xb,xc) to (x,y)
\advance\pgf@x by-\pgf@xb%
\advance\pgf@y by-\pgf@yb%
\advance\pgf@xc by-\pgf@xb%
\advance\pgf@yc by-\pgf@yb%
% Scalar product
\pgf@xd=\pgf@sys@tonumber{\pgf@xc}\pgf@x%
\advance\pgf@xd by\pgf@sys@tonumber{\pgf@yc}\pgf@y%
\pgf@yd=\pgf@sys@tonumber{\pgf@x}\pgf@x%
\advance\pgf@yd by\pgf@sys@tonumber{\pgf@y}\pgf@y%
\divide\pgf@xd by\pgf@sys@tonumber{\pgf@yd}
% and add
\advance\pgf@xb by\pgf@sys@tonumber{\pgf@xd}\pgf@x%
\advance\pgf@yb by\pgf@sys@tonumber{\pgf@xd}\pgf@y%
\tikz@cc@mid@checks%
}
\makeatother
\begin{document}
\begin{tikzpicture}
%A right triangle is drawn.
\path (0,0) coordinate (A) ({(1/4)*16},0) coordinate (B) ({(1/4)*12},{(1/4)*(4*sqrt(3))}) coordinate (C);
\draw (A) -- (B) -- (C) -- cycle;
%The vertices are labeled.
\node[anchor=north, inner sep=0, font=\footnotesize] at ($(A) +(0,-0.15)$){$A$};
\node[anchor=north, inner sep=0, font=\footnotesize] at ($(B) +(0,-0.15)$){$B$};
\node[anchor=south, inner sep=0, font=\footnotesize] at ($(C) +(0,0.15)$){$C$};
%A right-angle mark is drawn at C.
\coordinate (U) at ($(C)!5mm!45:(A)$);
\draw ($(A)!(U)!(C)$) -- (U) -- ($(B)!(U)!(C)$);
\draw[green] let \p1=($(B)-(C)$), \n1={atan(\y1/\x1)} in (U) -- ($(U) +({\n1+180}:0.5)$);
\draw[fill=green] ($(A)!(U)!(C)$) circle (1pt);
%The foot of the altitude is labeled F.
\coordinate (F) at ({(1/4)*(12)},0);
\draw[dashed] (F) -- (C);
%A right-angle mark is drawn at F.
\coordinate (V) at ($(F)!3.25mm!-45:(A)$);
\draw ($(A)!(V)!(B)$) -- (V) -- ($(C)!(V)!(F)$);
\end{tikzpicture}
\end{document}
附言
包tkz-euclide
通过计算两条特定线的交点来实现正交投影。这涉及到更多的算法,它们由包完成fp
。
毕竟,我认为修复calc
库而不是要求用户放弃它仍然是一个很好的做法。
答案3
尝试反转坐标计算的顺序:
\draw ($(C)!(U)!(A)$) -- (U) -- ($(C)!(U)!(B)$);
我尝试了一下您的示例,发现这对我有用。说实话:我不知道为什么。