我现在正在学习 tikz,它非常慢,但我正在慢慢学习。我正在尝试重现下面的图像。
这是我目前的代码。这基本上是从 pgf 手册中摘录的。
\documentclass[10pt,a4paper]{article}
\usepackage{mathtools}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{backgrounds}
\usepgflibrary{shapes}
\usetikzlibrary{through}
\begin{document}
\begin{figure}[!htpb] \centering
\begin{tikzpicture}
\foreach \a in {5,...,5}{
\draw[blue, dashed] (\a*2,0) circle(0.5cm);
\node[regular polygon, regular polygon sides=\a, minimum size=1cm, draw] at (\a*2,0) {};
}
\end{tikzpicture}
\end{figure}
\end{document}
此代码存在一些问题
- 我如何缩放该图像?
- 我该如何标记每一侧?
- 再说一次,我该如何做出那个令人讨厌的角度?
- 有没有办法对 n 边形执行此操作?
当我使用简单的方法缩放图像时,\begin{tikzpicture}[scale=3]...
圆圈只变大了。手动标记每个点有点繁琐。=(
编辑:我做到了 WOEEE 虽然代码很丑陋......:D:DD:
\documentclass[10pt,a4paper]{article}
\usepackage{mathtools}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{backgrounds}
\usepgflibrary{shapes}
\usetikzlibrary{through}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}
\begin{document}
\begin{figure}[!htbp]
\centering
\Large
\begin{tikzpicture}[scale=1]
\node (A) [draw,thick,regular polygon, regular polygon sides=6, minimum size=7cm,outer sep=0pt,fill=gray!20] {};
\node at (A.corner 1) [anchor=360/6*(1-1)+270] {$D$};
\node at (A.corner 2) [anchor=360/6*(2-1)+270] {$E$};
\node at (A.corner 3) [anchor=360/6*(3-1)+270] {$F$};
\node at (A.corner 4) [anchor=360/6*(4-1)+270] {$A$};
\node at (A.corner 5) [anchor=360/6*(5-1)+270] {$B$};
\node at (A.corner 6) [anchor=360/6*(5-1)+270] {$C$};
\node at (A.corner 4) [right,above] {\hspace{3.5cm}$AB=16$cm};
\coordinate [label=above:\textcolor{blue}{$S$}] (S) at (0.95,1);
\draw[gray, thick, dashed] (0,0) circle(3.52cm);
\path[draw] (0.7,-0.3) node {$\alpha$};
{
\begin{pgfonlayer}{foreground}
\draw[gray,thick, dashed] (A.corner 4) -- (S) -- (A.corner 5);
\end{pgfonlayer}
}
\begin{scope}
\path[clip] (S) -- (A.corner 4) -- (A.corner 5) -- cycle;
\draw [red, fill=red!20] (S) circle (30pt);
\draw [black] (S) circle (30pt);
\end{scope}
\end{tikzpicture}
\end{figure}
\end{document}
答案1
对于缩放,请添加transform shape
选项。不过,这可能看起来不太好。您最好修改和minimum size
。circle
要标记边,您可以distance modifiers
在锚点上使用,角点也是如此。对于角度,您可以使用tkz-euclid
或(如果您知道角度(或者愿意像我一样猜测))您可以绘制一个圆弧。要将其推广到 n 边形,请使用参数而不是 for 循环(现在什么都不做......)并使用它进行绘制。当然,角度和对应的AB
线将不再正确,但标签会正确。代码如下所示:
\documentclass[10pt,a4paper]{article}
\usepackage{mathtools}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{backgrounds}
\usepgflibrary{shapes}
\usetikzlibrary{through}
\begin{document}
\begin{figure}[!htpb] \centering
\begin{tikzpicture}
\pgfmathsetmacro{\a}{6}
\newcounter{temp}
\draw[dashed] (\a*2,0) circle(3cm);
\node[regular polygon, regular polygon sides=\a, minimum size=6cm, draw, blue, fill=blue!20] (poly) at (\a*2,0) {};
\foreach [count=\side] \siide in {2,3,...,\a,1}{
\pgfmathtruncatemacro{\opp}{mod(\side+\a/2,\a)}
\pgfmathtruncatemacro{\opp}{ifthenelse(equal(\opp,0),\a,\opp)}
\pgfmathtruncatemacro{\opi}{ifthenelse(equal(mod(\a,2),0),1,0)}
\def\oppp{\ifnum\opi=0 poly.side \opp\else poly.corner \opp\fi}
\node at ($(poly.side \side)!.15!270:(poly.corner \siide)$) {\side};
\node at ($(\oppp)!1.05!(poly.corner \side)$) {\setcounter{temp}{\side}\Alph{temp}};
}
\coordinate (S) at ($(poly.corner 5) + (100:3)$);
\begin{scope}
\path[clip] (poly.corner 4) -- (S) -- (poly.corner 5) -- cycle;
\path[draw,blue,fill=blue!50] (S) circle[radius=.4];
\path (S) ++(255:.6) node {$\alpha$};
\end{scope}
\node at ($(poly.corner 4)!.5!(poly.corner 5)$) [above] {$DE = 16$cm};
\node at (S) [above] {S};
\path[draw,dashed] (poly.corner 5) -- (S) -- (poly.corner 4);
\end{tikzpicture}
\end{figure}
\end{document}
为了稍微澄清一下代码,距离修饰符的工作方式如下:表示取从到 的线上的(A)!x!a:(B)
因子点,然后围绕 度旋转。这使我们能够将标签大致放置在我们想要的位置,而无需明确设置它们(对于较大的多边形,角度可能需要稍微调整)。x
A
B
a
A
输出结果如下:
编辑:更改了代码以放置标签以使用对角。如果边数为奇数,则使用对边。这样,对于几乎任何 值,标签的放置都适用于 n 边形。n
我还更改了角度以使用裁剪方法而不是估计它。最后,我改变了线上绘制节点的方式,以确保颜色没有差异。
结果看起来如下,显示了正常的六边形和九边形:
答案2
这里有一个使用 的解决方案tkz-euclide
。使用此方法,缩放图片没有问题。现在可以轻松地基于两个点构建一个正多边形。使用具有形状的节点不是很容易,regular polygon
因为如果您需要从两个顶点构造多边形,则您不知道这个多边形的中心。下一个方法显示如何使用我的包或直接使用 来构建这个中心tikz
。为边添加标签没有问题,但为顶点添加标签更复杂。一个简单的解决方案是使用从中心G
和顶点的路径。对于最后一个问题,很容易绘制一个有n
边的正多边形。关于我的解决方案,最好创建一个宏来构建一个有两个顶点或一个中心和一个顶点的正多边形。
\documentclass{article}
\usepackage{tkz-euclide}
\usetkzobj{all}
\begin{document}
\begin{center}
\begin{tikzpicture} [scale=.8]% no problem with scale
\tkzDefPoint(-1,-2){A} % with tikz you use coordinate
\tkzDefPoint(4,2){B}
\coordinate (S) at ($(A) + (60:7)$); % it's possible to use tikz's method
% \coordinate (mAB) at ($(A)!.5!(B)$); with tkz-euclide we need
\tkzDefMidPoint(A,B)\tkzGetPoint{mAB}
% 90*(n-2)/n with n sides to generalize the next method to get the center G
\path let \p1 = ($ (mAB) - (A) $)
in
coordinate (G) at ($ (mAB) ! veclen(\x1,\y1)*tan(60) !90: (B) $);
\tkzDrawCircle(G,A) with tikz you need to write
%\node (H) [draw,circle through=(B)] at (G) {};
% now I need to get others points of the polygon. It's possible to create a macro
\tkzInterCC(B,G)(G,A)\tkzGetPoints{A}{C}
\tkzInterCC(C,G)(G,A)\tkzGetPoints{B}{D}
\tkzInterCC(D,G)(G,A)\tkzGetPoints{C}{E}
\tkzInterCC(E,G)(G,A)\tkzGetPoints{D}{F}
\tkzDrawPolygon[fill=blue!10](A,B,C,D,E,F)
\tkzDrawSegments(F,S S,A)
\tkzDrawPoints(A,B,C,D,E,F,G,S)
\tkzMarkAngle[mark=||,arc=lll,size=2 cm,mkcolor=red](F,S,A)
\tkzLabelAngle(F,S,A){$\alpha$}
\end{tikzpicture}
\end{center}
\end{document}
可以用tikz
或用书写标签tkz-euclide
更新 :
我意识到我没有宏可以构建正多边形在 tkz-euclide 中。你现在可以在我的网站上找到阿尔特蒙杜斯一个名为 tkz-obj-polygons.tex 的测试版文件,您可以下载这里。答案的新版本是:
\documentclass{article}
\usepackage{tkz-euclide}
\usetkzobj{all}
\begin{document}
\begin{center}
\begin{tikzpicture} [scale=.75]
\tkzDefPoint(-1,-2){A}
\tkzDefPoint(1,3){B}
\tkzDefRegPolygon[side,sides=6](A,B) \tkzGetPoint{O}
\tkzDrawPolygon[fill=black!10,draw=blue](P1,P2,P3,P4,P5,P6)
\tkzLabelRegPolygon[sep=1.05](O){A,...,F}
\tkzDrawCircle[dashed](O,A)
\tkzLabelSegment[above,sloped,midway](A,B){\(A B = 16m\)}
\foreach \i [count=\xi from 1] in {2,...,6,1}
{%
\tkzDefMidPoint(P\xi,P\i)
\path (O) to [pos=1.1] node {\xi} (tkzPointResult) ;}
\tkzGetRandPointOn[segment = P3--P5]{S}
\tkzDrawSegments[thick,dashed,red](A,S S,B)
\tkzDrawPoints(P1,P2,P3,P4,P5,P6,S)
\tkzLabelPoint[left,above](S){$S$}
\tkzDrawSector[R with nodes,fill=red!20](S,2 cm)(A,B)
\tkzLabelAngle[pos=1.5](A,S,B){$\alpha$}
\end{tikzpicture}
\end{center}
\end{document}
解释:
\tkzDefRegPolygon
是定义正多边形的宏。使用选项,你可以用 a和 acenter
定义一个多边形,但使用选项,你需要给出多边形的两个连续点。默认情况下,尺寸数量为 5,但可以使用选项。如果使用选项,你可以使用宏找到多边形的中心center
point
side
sides
side
\tkzGetPoint
\tkzLabelRegPolygon
可用于向顶点添加标签。标签放置在从中心到顶点的线上。tkzGetRandPointOn
这是一个获取随机点的旧宏。这里我获取了线的一个点CE
。\tkzDrawSector
对于填充扇区很有用。您需要知道中心和两个点来定义起点和终点。2 cm
是填充扇区的半径。
结果 :
答案3
我很高兴看到 Altermundus 发布了使用 tkz-euclide 的方法。关于这个图表,我首先想说两点,其中之一是,如果你正在制作几何图表,那么你应该看看 tkz 包(我自己对它们了解不多,但我见过 Altermundus 使用它们制作了一些非常出色的图表)。
我想说的另一件事是,虽然使用节点来绘制特定形状很诱人,但它也有缺点。节点旨在保存文本,它们的一些行为源于此 - 特别是它们如何受到变换的影响。可以规避这些行为,但你必须知道如何做。
但这不是一个答案,而是一个评论。
我确实有一个答案给你,而且这个答案不使用节点。
\documentclass{article}
%\url{http://tex.stackexchange.com/q/35266/86}
\usepackage{tikz}
\usetikzlibrary{calc}
\makeatletter
% This provides a translation from numbers to letters for labelling
% the vertices
\newcommand\numToAlpha[1]{\@Alph#1}
\makeatother
\begin{document}
\begin{tikzpicture}
% This draws the circle
\draw[dashed] (0,0) circle[radius=3cm];
% This draws,fills and labels the polygon
\draw[ultra thick,blue,fill=blue!25] (0,0)
% Set the number of sides
let \n1=7 in
% We start so that the second line is the lower horizontal
% This means that the first vertex that we label is the left
% end of the lower horizontal
({-90 - 3*360/(2*\n1)}:3)
% Now we iterate over the edges
\foreach \l in {1,...,\n1} {
% This saves our next angle (as we use it twice)
let \n2={-90 + (2 * \l - 3) * 360/(2 * \n1)} in
% This draws the edge and labels it
% As our first edge is actually the last one, our label needs
% shifting round (modulo the number of edges)
-- node[auto,swap,text=black] {\pgfmathparse{int(Mod(\l-2,\n1)+1)}\pgfmathresult}
% This is the endpoint of the edge
(\n2:3)
% This is the label at the endpoint, we could have chosen to
% label the start of the edge, but then the offset would have
% been slightly more complicated.
% We also save these nodes since we'll want two of them later
node[label={[text=black]\n2:{\numToAlpha{\l}}}] (\numToAlpha{\l}) {}
};
% This is our point "S", I chose coordinates at random
\fill (1,.5) circle[radius=2pt] coordinate (S) node[above] {S};
% This draws the dashed lines to the edge
\draw[dashed] (A) -- (S) -- (B);
\begin{scope}
% My method for drawing the angle is sneaky: I clip a circle
% against the dashed path
\clip (A) -- (S) -- (B);
\draw[blue,ultra thick,fill=blue!50] (S) circle[radius=1cm];
\end{scope}
% Then to position the alpha, I use an invisible path that
% goes from S to the midpoint of A-B
\path ($(S)!1.2cm!($(B)!.5!(A)$)$) node {\(\alpha\)};
% Finally, we label the edge A-B with its distance
\path (A) -- node[auto] {\(A B = 16m\)} (B);
\end{tikzpicture}
\end{document}
结果如下:
(忘记了text=black
。代码是正确的,但图片中的数字是蓝色的而不是黑色的。)