![怎样改善身材?](https://linux22.com/image/416922/%E6%80%8E%E6%A0%B7%E6%94%B9%E5%96%84%E8%BA%AB%E6%9D%90%EF%BC%9F.png)
我想要绘制彼此相切且与大圆相切的小圆,如图所示。
但是,我的图形并没有像我希望的那样出现,小圆圈实际上与大圆圈相切。
\documentclass[12pt]{article}
\usepackage{tikz}
\begin{document}
\begin{center}
\begin{tikzpicture}[scale=1.2]
\draw[ultra thick, red!95] (0,0) circle [radius=2.9];
\draw[ultra thick, blue!90] (3.4,2) circle [radius=1];
\draw[ultra thick, yellow!90] (2,3.4) circle [radius=1];
\draw[ultra thick, green!90] (0,4) circle [radius=1];
\draw[ultra thick, cyan] (-2,3.4) circle [radius=1];
\draw[ultra thick, black] (-3.4,2) circle [radius=1];
\draw[ultra thick, green!90] (-4,0) circle [radius=1];
\draw[ultra thick, blue!90] (-3.4,-2) circle [radius=1];
\draw[ultra thick, cyan] (-2,-3.4) circle [radius=1];
\draw[ultra thick, blue!90] (0,-4) circle [radius=1];
\draw[ultra thick, yellow!95] (2,-3.4) circle [radius=1];
\draw[ultra thick, black] (3.4,-2) circle [radius=1];
\draw[ultra thick, green!90] (4,0) circle [radius=1];
\node at (2.2,2.2) {$\mathbf{S_{1}}$};
\node at (0.8,3) {$\mathbf{S_{2}}$};
\node at (-0.8,3) {$\mathbf{S_{3}}$};
\node at (-2.2,2.2){$\mathbf{S_{4}}$};
\node at (-3,0.8) {$\mathbf{S_{5}}$};
\node at (-3,-0.8) {$\mathbf{S_{6}}$};
\node at (-2.2,-2.2){$\mathbf{S_{7}}$};
\node at (-0.8,-3){$\mathbf{S_{8}}$};
\node at (0.8,-3) {$\mathbf{S_{9}}$};
\node at (2.2,-2.2) {$\mathbf{S_{10}}$};
\node at (3,-0.8) {$\mathbf{S_{11}}$};
\node at (3,0.8) {$\mathbf{S_{12}}$};
\end{tikzpicture}
\end{center}
\end{document}
答案1
这里有一个限制。您不能拥有任意大小的半径,以及任意数量的圆,并且让它们都像您描述的那样相切。
下面的代码确保它们相切,并根据给定的大圆半径计算小圆所需的半径。
\documentclass[12pt]{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{center}
\begin{tikzpicture}[scale=1.2]
\def\numcircles{12}
\def\bigradius{2.9}
% define the colors beforehand so they're in an array and easy to use
\def\circlecolors{blue!90, yellow!90, green!90, cyan, black, green!90, blue!90, cyan, blue!90, yellow!95, black, green!90}
% I'm doing trigonometry here....
\pgfmathsetmacro\s{sin(360/(2*\numcircles))}
\pgfmathsetmacro\smallradius{\bigradius * \s / (1-\s)}%
\draw[ultra thick, red!95] (0,0) circle [radius=\bigradius];
% Do the circles & labels in a loop, instead of one-by-one.
\foreach\circcolor [count=\i,
evaluate={\i as \angle using {(3-\i)*360/\numcircles}}] in \circlecolors {
% this "evaluate" statement gives us the angle. The "(3-\i)"
% is to shift the starting position of the labels to match the ones in
% your picture. The negative is to ensure it goes counter-clockwise.
% first draw the circle ....
\draw[ultra thick,color=\circcolor] (\angle:{\smallradius+\bigradius}) circle [radius={\smallradius}];
% and then add the label at an offset equal to half the angle
\node at ({\angle+180/\numcircles}:{\bigradius+0.2}){$S_{\i}$};
}
\end{tikzpicture}
\end{center}
\end{document}
得到下图的结果:
线条重叠,但可以通过减少\smallradius
线条宽度的数量来消除这种情况。
至于三角函数,只需画两个与大圆相切的小圆,并将它们的中心用线段连接起来。设“r”为大圆半径,“a”为小圆中心之间的角度,“x”为小圆半径。应该立即得到sin(a / 2) = x / (x+r)
,我刚刚解出了 x。
答案2
类似这样的情况?也许你需要进行一些计算来将线宽从半径中排除。然后它就变成了一个不难解决的数学问题。
下面pic
可以画一个大圆,以及围绕大圆任意一个半径和线宽相同的小圆。
选项
r
:大圆的半径num
:小圆圈的数量small width
:小圆圈的线宽big width
:大圆的线宽pos
:大圆边界到节点的距离color 0
:大圆圈的颜色color i
(i >= 1): 第 i 个小圆圈的颜色
第一个小圆位于 上0 deg
。如果有 n 个小圆,则第二个小圆位于 上,360/n deg
依此类推。
第一个节点位于第一个和第二个小圆圈之间,picname-1
依此类推。
\documentclass[tikz, border=1cm]{standalone}
\usetikzlibrary{fpu}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand {\myfor} { m +m } {
\int_step_variable:nNn {#1} \l_for_tl {\def\forvar{\tl_use:N \l_for_tl}#2}
}
\ExplSyntaxOff
% predefine
\myfor{50}{
\pgfkeys{/multicircles/color \forvar/.initial=black}
}
\makeatletter
\newlength\mc@r
\newlength\mc@R
\newlength\mc@rR
\newlength\mc@node
\tikzset{
mc/.pic={
\pgfkeys{/pgf/fpu, /pgf/fpu/output format=fixed}
\pgfmathsetlength{\mc@R}{\mc@radius-\mc@big@width/2}
\pgfmathsetmacro{\mc@ang}{360/\mc@num}
\pgfmathsetmacro{\mc@cos}{90-\mc@ang/2}
\pgfmathsetlength{\mc@r}{cos(\mc@cos)/(1-cos(\mc@cos))*\mc@radius-\mc@small@width/2}
\pgfmathsetlength{\mc@rR}{\mc@radius/(1-cos(\mc@cos))}
\pgfmathsetlength{\mc@node}{\mc@pos*\mc@rR*cos(\mc@ang/2)+(1-\mc@pos)*\mc@R}
\pgfkeys{/pgf/fpu=false}
\draw [\mc@color@main, line width=\mc@big@width] (0, 0) circle (\mc@R);
\foreach \i in {1,...,\mc@num} {
\def\temp@color{\pgfkeysvalueof{/multicircles/color \i}}
\draw [\temp@color, line width=\mc@small@width] ({(\i-1)*\mc@ang}:\mc@rR) circle (\mc@r);
\coordinate (-\i) at ({(\i-0.5)*\mc@ang}:\mc@node);
}
},
/multicircles/.search also=/tikz,
/multicircles/.cd,
color 0/.store in=\mc@color@main,
color 0=black,
num/.store in=\mc@num, num=6,
r/.store in=\mc@radius, r=1cm,
big width/.store in=\mc@big@width,
big width=1.6pt,
small width/.store in=\mc@small@width,
small width=1.6pt,
pos/.store in=\mc@pos, pos=.3,
}
\makeatother
\newcommand{\multicircles}[1][]{
\pic [pic type=mc, /multicircles/.cd,#1];
}
\newcommand{\multicirclesset}[1]{\pgfqkeys{/multicircles}{#1}}
\multicirclesset{
colors/.code args={#1!#2!#3}{
\myfor{#2}{
\pgfmathparse{\forvar/#2*100}
\edef\temp{
\noexpand\multicirclesset{color \forvar=#1!\pgfmathresult!#3}
}
\temp
}
}
}
\begin{document}
\begin{tikzpicture}
\multicircles[
r=2cm, num=6, color 0=red!60,
big width=3pt, small width=3pt,
colors=red!6!blue,
at={(0, 0)},
name=a,
]
\foreach \i in {1,...,6} {
\node [font=\small] at (a-\i) {$S_{\i}$};
}
\multicircles[
r=3cm, num=12, color 0=red!60,
big width=2pt, small width=4pt,
colors=yellow!12!cyan,
at={(12, 0)},
name=b,
]
\foreach \i in {1,...,12} {
\node [font=\tiny] at (b-\i) {$S_{\i}$};
}
\multicircles[
r=4cm, num=19, color 0=red!60,
big width=8pt, small width=5pt,
colors=green!19!teal,
at={(24, 0)},
name=c,
pos=-.5,
]
\foreach \i in {1,...,19} {
\node at (c-\i) {$S_{\i}$};
}
\end{tikzpicture}
\end{document}