梅威瑟:
\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}
甚至可以更进一步,摆脱交叉点库,让事情变得更加 Ti钾Zy 通过使用初等三角学根据笛卡尔坐标确定中心。
\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
请使用包fp
。Tikz
和TeX
是非常好的工具,但它们的计算能力有限,如果连接计算,很快就会出现错误。例如,您可以在手册中查看如何绘制三角形的高。高交点定义非常糟糕。
进行计算的最佳方法是使用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}