Tikz-Euclid、内切圆和计算坐标

Tikz-Euclid、内切圆和计算坐标

梅威瑟:

\documentclass[tikz, border=1cm]{standalone}
\usepackage{tkz-euclide}
\begin{document}
\begin{tikzpicture}
    \coordinate (A) at (0,0);
    \coordinate (B) at (4,0);
    % \coordinate (C) at ($(A) + ({-60}:4)$);
    \coordinate (C) at (2,-3);

    \draw (A)--(B)--(C)--cycle;

    % circumcircle
    \tkzCircumCenter(A,B,C)\tkzGetPoint{O}
    % \tkzDrawPoint(O)
    \tkzDrawCircle(O,A)

    % incircle
    \tkzDefCircle[in](A,B,C)\tkzGetPoint{I}\tkzGetLength{rIN}
    \tkzDrawPoint(I)
    \tkzDrawCircle[R](I,\rIN pt)
\end{tikzpicture}  
\end{document}

给予,

在此处输入图片描述

\documentclass[tikz, border=1cm]{standalone}
\usepackage{tkz-euclide}
\begin{document}
\begin{tikzpicture}
    \coordinate (A) at (0,0);
    \coordinate (B) at (4,0);
    \coordinate (C) at ($(A) + ({-60}:4)$);
    % \coordinate (C) at (2,-3);

    \draw (A)--(B)--(C)--cycle;

    % circumcircle
    \tkzCircumCenter(A,B,C)\tkzGetPoint{O}
    % \tkzDrawPoint(O)
    \tkzDrawCircle(O,A)

    % incircle
    \tkzDefCircle[in](A,B,C)\tkzGetPoint{I}\tkzGetLength{rIN}
    \tkzDrawPoint(I)
    \tkzDrawCircle[R](I,\rIN pt)
\end{tikzpicture}  
\end{document}

给予,

在此处输入图片描述

我是否遗漏了某些东西,或者 tikz-euclid 使用计算出的坐标进行计算时出现了问题?(为什么会这样?)

附录

这种纯粹的tikz-euclid方式似乎也有问题:

\documentclass[tikz, border=1cm]{standalone}
\usepackage{tkz-euclide}
\usetkzobj{all}
\begin{document}
\begin{tikzpicture}
    \tkzDefPoint(0,0){A}
    \tkzDefPoint(4,0){B}
    \tkzDefTriangle[equilateral](B,A)
    \tkzGetPoint{D}
    \tkzDrawPolygon(B,A,D)

    % circumcircle
    \tkzCircumCenter(A,B,D)\tkzGetPoint{O}
    \tkzDrawCircle(O,A)

    % incircle
    \tkzDefCircle[in](A,B,D)\tkzGetPoint{I}\tkzGetLength{rIN}
    \tkzDrawPoint(I)
    \tkzDrawCircle[R](I,\rIN pt)
\end{tikzpicture}
\end{document}

给出:

在此处输入图片描述

答案1

我认为包的宏进行的计算存在数值不稳定性tkz-euclide。这与通过语法设置的坐标无关calc。要看到这一点,请考虑

\documentclass[tikz, border=1cm]{standalone}
\usepackage{tkz-euclide}
\begin{document}
\begin{tikzpicture}
    \coordinate (A) at (0,0);
    \coordinate (B) at (4,0);
    % \coordinate (C) at ($(A) + (2,-3)$); %({-60}:4)
    \coordinate (C) at ({-60.01}:4); %({-60}:4)
    % \coordinate (C) at (2,-3);

    \draw (A)--(B)--(C)--cycle;

    % circumcircle
    \tkzCircumCenter(A,B,C)\tkzGetPoint{O}
    % \tkzDrawPoint(O)
    \tkzDrawCircle(O,A)

    % incircle
    \tkzDefCircle[in](A,B,C)\tkzGetPoint{I}\tkzGetLength{rIN}
    \tkzDrawPoint(I)
     \tkzDrawCircle[R](I,\rIN pt)
\end{tikzpicture}  
\end{document}

在此处输入图片描述

一切都很酷(除了边界框,如果在计算辅助路径时tkz-euclide放置它,就可以正确计算overlay,但这与此无关)。

但是,如果我删除定义的角度的最后一位数字C,即

\coordinate (C) at ({-60}:4);

我明白你所得到的一切

在此处输入图片描述

我强调我甚至试图弄清楚内部发生了什么,只是因为我不会说法语并且不理解手册或代码中的很多内容。

结论:在我看来,您已经发现了一个问题tkz-euclide

附录:为什么会发生这种情况?为了理解这一点,让我们回顾一下内切圆是如何计算的。为此,我遵循这个很好的答案,使用海伦公式计算\inrad内切圆的半径。这告诉我们内切圆是与距离为 的边平行的线\incircle相交的地方。但是,对于给定的边,有两条距离为 的平行线。

\documentclass[tikz, border=1cm]{standalone}
\usepackage{tkz-euclide}
\begin{document}
% from https://tex.stackexchange.com/a/299451/121799
% calculate semiperimeter
% \pgfmathsetmacro{\semip}{(\sideA+\sideB+\sideC)/2}
% calculate radius of incircle: area (given by Heron's formula) divided by semiperimeter
% \pgfmathsetmacro{\inrad}{sqrt(\semip*(\semip-\sideA)*(\semip-\sideB)*(\semip-\sideC))/\semip}

\begin{tikzpicture}[globalize/.code n args={2}{\xdef#2{#1}}]
    \coordinate (A) at (0,0);
    \coordinate (B) at (4,0);
    % \coordinate (C) at ($(A) + (2,-3)$); %({-60}:4)
    \coordinate (C) at ({-60.01}:4); %({-60}:4)
    % \coordinate (C) at (2,-3);
    \path let \p1=($(A)-(B)$), \p2=($(B)-(C)$),\p3=($(C)-(A)$),
    \n1={0.5*(veclen(\x1,\y1)+veclen(\x2,\y2)+veclen(\x3,\y3))},
    \n2={sqrt(((\n1-veclen(\x1,\y1))/\n1))*sqrt((\n1-veclen(\x2,\y2))*(\n1-veclen(\x3,\y3)))}
    in  [globalize={\n2}{\inrad}];
    \foreach \X/\Y in {A/B,B/C,C/A}
    {\draw[gray,thin] ($(\X)!\inrad!90:(\Y)$) -- ($(\Y)!\inrad!-90:(\X)$);
    \draw[gray,thin] ($(\X)!\inrad!-90:(\Y)$) -- ($(\Y)!\inrad!90:(\X)$);}
    \draw (A)--(B)--(C)--cycle;

    % circumcircle
    \tkzCircumCenter(A,B,C)\tkzGetPoint{O}
    % \tkzDrawPoint(O)
    \tkzDrawCircle(O,A)

    % incircle
    \tkzDefCircle[in](A,B,C)\tkzGetPoint{I}\tkzGetLength{rIN}
    \tkzDrawPoint(I)
     \tkzDrawCircle[R](I,\rIN pt)
\end{tikzpicture}  
\end{document}

在此处输入图片描述

看这张图片,我认为tkz-euclide计算了错误(即外部)平行线的交点。这张图片还显示内切圆中心并不精确位于平行线的交点处。

这表明,至少只要tkz-euclide需要精通法语,就可以计算内切圆半径和中心,而无需该包,但遵循这个很好的答案

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{calc,intersections}
\begin{document}
\begin{tikzpicture}[globalize/.code n args={2}{\xdef#2{#1}}]
    \coordinate (A) at (0,0);
    \coordinate (B) at (4,0);
    \coordinate (C) at ($(A)+({-60}:4)$); 
    \draw (A) -- (B) -- (C) -- cycle;
    %
    \path let \p1=($(A)-(B)$), \p2=($(B)-(C)$),\p3=($(C)-(A)$),
    \n1={0.5*(veclen(\x1,\y1)+veclen(\x2,\y2)+veclen(\x3,\y3))},
    \n2={sqrt(((\n1-veclen(\x1,\y1))/\n1))*sqrt((\n1-veclen(\x2,\y2))*(\n1-veclen(\x3,\y3)))}
    in  [globalize={\n2}{\inrad}];
    \foreach \X/\Y in {A/B,B/C,C/A}
    {\path[name path global=path-\X-\Y-1] ($(\X)!\inrad!90:(\Y)$) -- ($(\Y)!\inrad!-90:(\X)$);
    \path[name path global=path-\X-\Y-2] ($(\X)!\inrad!-90:(\Y)$) -- ($(\Y)!\inrad!90:(\X)$);}
    \foreach \X in {1,2}
    {\foreach \Y in {1,2}
     {\path[name intersections={of={path-A-B-\X} and {path-B-C-\Y},total=\t}]
     \ifnum\t=1 
     (intersection-1) coordinate (incenter)
     \else
     \fi
     ;}
    }
    \draw (incenter) circle (\inrad);
\end{tikzpicture}
\end{document}

在此处输入图片描述

甚至可以更进一步,摆脱交叉点库,让事情变得更加 TiZy 通过使用初等三角根据笛卡尔坐标确定中心

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[incircle/.style n args={3}{%
insert path={
let \p1=($(#2)-(#1)$), \p2=($(#3)-(#1)$),\p3=($(#2)-(#3)$),
    \n1={0.5*(veclen(\x1,\y1)+veclen(\x2,\y2)+veclen(\x3,\y3))},
    \n2={sqrt(((\n1-veclen(\x1,\y1))/\n1))*sqrt((\n1-veclen(\x2,\y2))*(\n1-veclen(\x3,\y3)))},
    \n3={veclen(\x1,\y1)}, % length #1 -- #2
    \n4={veclen(\x2,\y2)}, % length #1 -- #3
    \n5={veclen(\x3,\y3)}, % length #2 -- #3
    \n6={\n3+\n4+\n5}
    in % \pgfextra{\typeout{\n1,\n2,\n3,\n4,\n5,\n6}}
    (${(\n5/\n6)}*(#1)+{(\n4/\n6)}*(#2)+{(\n3/\n6)}*(#3)$) circle (\n2)
}}]
    \coordinate (A) at (0,0);
    \coordinate (B) at (4,0);
    \coordinate (C) at ($(A)+({-60}:4)$); 
    \draw (A) -- (B) -- (C) -- cycle;
    %
    \draw[incircle={A}{B}{C}];
\end{tikzpicture}
\end{document}

这会产生与上述相同的输出。(在撰写本文时,我发现掌握所有情况绝非易事,而且也不能保证我做到了。也就是说,我对 Alain Matthes 的成就印象深刻。换句话说,尽管我确实认为 可能存在问题tkz-euclide,但也应该强调它总体上效果很好。)

答案2

您发现了一个错误...宏\tkzDefCircle[in]不正确。使用新版本的tkz-base和 后,该问题便消失了tkz-euclide

现在使用 tkz-euclide 的正确代码是

\documentclass[tikz, border=1cm]{standalone}
\usepackage{tkz-euclide}

\begin{document}
\begin{tikzpicture}
    \tkzDefPoint(0,0){A}
    \tkzDefPoint(4,0){B}
    \tkzDefTriangle[equilateral](B,A)
    \tkzGetPoint{D}
    \tkzDrawPolygon(B,A,D)

    % circumcircle
    \tkzCircumCenter(A,B,D)\tkzGetPoint{O}
    \tkzDrawCircle(O,A)

    % incircle
    \tkzDefCircle[in](A,B,D)\tkzGetPoint{I}\tkzGetLength{rIN}
    \tkzDrawPoint(I)
    \tkzDrawCircle[R](I,\rIN pt)
\end{tikzpicture}
\end{document}

现在您可以避免\usetkzobj{all}。主要模块被收费,只有非常特定的模块才能使用此宏调用。

现在如何、为什么、在哪里需要或者不需要使用 calc、tikz 等。

最好使用\tkzDefPoint而不是\coordinate使用,tkz-euclide因为如果您需要进行一些计算才能得到一个点,tkz-euclide请使用包fpTikzTeX是非常好的工具,但它们的计算能力有限,如果连接计算,很快就会出现错误。例如,您可以在手册中查看如何绘制三角形的高。高交点定义非常糟糕。

进行计算的最佳方法是使用lua。也许下一个版本的 euclide 将分为两部分。第一部分将用于lua定义点,然后第二部分将使用 tikz 绘制不同的对象。

现在你可以使用 calc 语法来获取坐标,但你还有其他方法

\documentclass[tikz, border=1cm]{standalone}
\usepackage{tkz-euclide}
\begin{document}

\begin{tikzpicture}
    \tkzDefPoint(0,0){A}
    \tkzDefPoint(4,0){B}
    \coordinate (C) at ($(A) + ({60}:4)$);
    % Better is \tkzDefTriangle[equilateral](B,A)
    % or \tkzDefShiftPoint[A](-60:4){C}
    % possible 
        % \begin{scope}[shift={(A)}]
        %    \tkzDefPoint(-60:4){C}
        % \end{scope}
    \tkzDrawPolygon(B,A,C)

    % circumcircle
    \tkzCircumCenter(A,B,C)\tkzGetPoint{O}
    \tkzDrawPoint(O)
    \tkzDrawCircle(O,A)
    
    % incircle
     \tkzDefCircle[in](A,B,C)\tkzGetPoint{I}\tkzGetLength{rIN}
     \tkzDrawCircle[R,color=red](I,\rIN pt)
\end{tikzpicture}  
\end{document}

相关内容