我正在写一个文档,其中我barycentric
多次使用坐标系。因此 MWE 看起来像这样
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\fill (1,4) circle (1pt) coordinate (a) node[above] {$A$}
(0,0) circle (1pt) coordinate (b) node[below] {$B$}
(5,0) circle (1pt) coordinate (c) node[below] {$C$};
\draw (a) -- (b) -- (c) -- cycle;
\fill[red] (barycentric cs:a=1/3,b=1/3,c=1/3) circle (1pt) node[below] {$G$};
\end{tikzpicture}
\end{document}
但是看起来不太简洁,不是吗?当我需要barycentric
大量使用时,这确实很不方便。
我想要这样的东西:
\tikzset{barycentric coordinates={(a),(b),(c)}}
...
\path[barycentric] (1/3,1/3,1/3) coordinate (x);
相当于
\path (barycentric cs:a=1/3,b=1/3,c=1/3) coordinate (x);
是否可以?
当然我可以为此定义一个宏(我正在使用这种方式),但我认为上面的方法更加灵活。
答案1
如果你总是有三个(或更少)坐标,那就没有问题。Ti钾Z 开箱即用。你只需要
\begin{scope}[x={(a)},y={(b)},z={(c)}]
<in this scope your syntax works>
\end{scope}
完整 MWE:
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\fill (1,4) circle (1pt) coordinate (a) node[above] {$A$}
(0,0) circle (1pt) coordinate (b) node[below] {$B$}
(5,0) circle (1pt) coordinate (c) node[below] {$C$};
\draw (a) -- (b) -- (c) -- cycle;
\fill[red] (barycentric cs:a=1/3,b=1/3,c=1/3) circle (1pt) node[below] {$G$};
\begin{scope}[x={(a)},y={(b)},z={(c)}]
\draw[blue] (1/3,1/3,1/3) circle[radius=2pt];
\end{scope}
\end{tikzpicture}
\end{document}
但是,这不是真正的重心坐标系,因为它没有进行归一化。不过,在您的示例中,所有分量相加为 1,这没问题。
如果您想使用类似于您的语法的东西,允许任意数量的坐标并规范化坐标,那么请考虑这一点:
\documentclass[tikz]{standalone}
\makeatletter
\tikzdeclarecoordinatesystem{b}
{%
{%
\pgf@xa=0pt% point
\pgf@ya=0pt%
\pgf@xb=0pt% sum
\pgfutil@tempcnta=0%
\tikz@b@dolist#1,,%
\pgfmathparse{1/\the\pgf@xb}%
\global\pgf@x=\pgfmathresult\pgf@xa%
\global\pgf@y=\pgfmathresult\pgf@ya%
}%
}%
\def\tikz@b@dolist#1,{%
\def\tikz@temp{#1}%
\ifx\tikz@temp\pgfutil@empty%
\else
\pgf@process{\pgfpointanchor{\csname tikz@bcoord@\the\pgfutil@tempcnta\endcsname}{center}}%
\pgfmathparse{#1}%
\advance\pgf@xa by\pgfmathresult\pgf@x%
\advance\pgf@ya by\pgfmathresult\pgf@y%
\advance\pgf@xb by\pgfmathresult pt%
\advance\pgfutil@tempcnta1%
\expandafter\tikz@b@dolist%
\fi%
}%
\tikzset{barycentric coordinates/.code={
\pgfutil@tempcnta=0%
\tikz@bc@dolist#1,,%
}}
\def\tikz@bc@dolist#1,{%
\def\tikz@temp{#1}%
\ifx\tikz@temp\pgfutil@empty%
\else
\expandafter\edef\csname tikz@bcoord@\the\pgfutil@tempcnta\endcsname{#1}%
\advance\pgfutil@tempcnta1%
\expandafter\tikz@bc@dolist%
\fi%
}%
\makeatother
\begin{document}
\begin{tikzpicture}
\fill (1,4) circle (1pt) coordinate (a) node[above] {$A$}
(0,0) circle (1pt) coordinate (b) node[below] {$B$}
(5,0) circle (1pt) coordinate (c) node[below] {$C$}
(4,3) circle (1pt) coordinate (d) node[below] {$D$} ;
\draw (a) -- (b) -- (c) -- (d) -- cycle;
\fill[red] (barycentric cs:a=1/3,b=1/3,c=1/3) circle (1pt) node[below] {$G$};
\begin{scope}[barycentric coordinates={a,b,c}]
\draw (b cs:1,1,1) circle[radius=2pt];
\end{scope}
\fill[red] (barycentric cs:a=1/4,b=1/4,c=1/4,d=1/4) circle (1pt) node[below] {$H$};
\begin{scope}[barycentric coordinates={a,b,c,d}]
\draw (b cs:1,1,1,1) circle[radius=2pt];
\end{scope}
\end{tikzpicture}
\end{document}
您仍然需要编写b cs:
,但除此之外,这是您提议的语法。(可以消除添加的需要b cs:
,请参阅这里但是这会使该代码更加难以处理,而且据我所知,这只适用于 2 或 3 个坐标。)
由于这一点并不为人熟知,我还要提一下可以\usepgfplotslibrary{ternary}
在 pgfplots 中加载的三元轴。它们也会按照您想要的方式解析坐标。
答案2
我更喜欢 A=1/3,B=1/3,C=1/3 的符号 [更简洁,更易读],但这只是个人喜好问题。以下是我使用 tkz-euclide 的方式
\documentclass[border=.25cm]{standalone}
\usepackage{tkz-euclide}
\begin{document}
\begin{tikzpicture}
\tkzDefPoints{1/4/A,0/0/B,5/0/C,4/3/D}
\tkzDefBarycentricPoint(A=1/3,B=1/3,C=1/3) \tkzGetPoint{G}
\tkzDefBarycentricPoint(A=1/4,B=1/4,C=1/4,D=1/4) \tkzGetPoint{H}
\tkzDrawPolygon(A,...,D)
\tkzDrawPoints[red](G,H)
\tkzDrawPoints(A,B,C,D)
\tkzLabelPoints(A,B,C,D,G,H)
\end{tikzpicture}
\end{document}
% why not
% \tkzDefBarycentricPoint(A=1,B=1,C=1) \tkzGetPoint{G}
% \tkzDefBarycentricPoint(A=1,B=1,C=1,D=1) \tkzGetPoint{H}