附言

附言

我有一个直角三角形 △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)$);

我尝试了一下您的示例,发现这对我有用。说实话:我不知道为什么。

相关内容