如何绘制一个半径为 r 的圆,并在其中插入所有可能的宽度为 s 的正方形?如果可能,每个正方形都可以在正方形的角上穿过外围。正方形必须像网格一样并排放置。
例如,我可以在右上轴上构造一个,其中 r = 10 和 s = 1。但是,我似乎无法同时让它对所有其他轴起作用。有办法解决这个问题吗?
此外,在我的“条件”语句中,正方形的某些部分似乎位于外围之外。这对我来说很难添加更多条件来确保所有正方形都必须留在圆圈内。我试图翻译该图以提供帮助,但我不知道这是否是应该这样做的方式。
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\foreach \x in {0,...,10}
\foreach \y in {0,...,10}
{
\pgfmathparse{(\x+1)^2+(\y+1)^2<=100} %Condition of squares to stay inside the circle.
%This circle is translated to make it work.
\ifnum\pgfmathresult=1
\filldraw[fill=blue!50] (\x,\y) rectangle (\x+1,\y+1); %Colouring the squares
\fi
}
\draw (0,0) circle [radius=10]; %Circle
\end{tikzpicture}
\end{document}
答案1
由于您的图表在所有可能的形式下都是对称的,因此您只需计算一个象限并绘制所有四个象限。
您也不必检查所有 100 个可能的方块,您只需要允许的顶部方块,然后绘制所有位于其下方的方块。
(从技术上讲,如果你知道X剥离,说之间X= 0 且X= 1 它只会上升到是= 9,你还知道是= 0 且是= 1 它只会上升到X=9。)
当 (10, 0) 被评估为角点时,该at y0.0
样式用于禁用单线绘制。(实际上,如果是= 0 将其包裹在
\unless\ifdim\y pt=0pt\relax
…
\fi
以获得更低级的方法。
下面我的解决方案包装在一个宏中\tikzcirclewithsquares
,该宏将其可选参数应用于/tikz/cws
名称空间中
- 三条路径的样式为(圆形、矩形、网格)
- 值
radius
和step
可以设置 - 是否只应显示圆内的正方形,还是也
outside = true
应显示圆周上的正方形()。
后者的设置使得从外部接触圆的正方形不出现。
事实上让它们显示出来几乎更容易,但我们必须考虑那些位于圆圈左侧和右侧的方块,目前还没有考虑到这些方块,因为所有的方块都会有X< 半径。
代码
\documentclass[tikz]{standalone}
\newif\iftikzcirclewithsquaresoutside
\tikzset{cws/.cd,
circle/.style=draw, grid/.style=draw,
rect/.style={fill=blue!50},
every/.style={
/pgf/declare function={
cwsRadius=\pgfkeysvalueof{/tikz/cws/radius};
cwsStep=\pgfkeysvalueof{/tikz/cws/step};}},
radius/.initial=10, step/.initial=1,
outside/.is if=tikzcirclewithsquaresoutside}
\newcommand*\tikzcirclewithsquares[1][]{%
\scope[cws/.cd,every,#1]
\foreach[
parse=true,
remember=\notY as \lastNotY (initially cwsRadius/cwsStep),% sqrt(R²)/Step
evaluate={
\cwsX = cwsStep*\step;
\notY = sqrt(cwsRadius*cwsRadius-\cwsX*\cwsX)/cwsStep;
\cwsY = \iftikzcirclewithsquaresoutside ceil\else floor\fi
(\iftikzcirclewithsquaresoutside\lastNotY\else\notY\fi)*cwsStep;},
/tikz/at y0.0/.style=\unless\iftikzcirclewithsquaresoutside path only\fi,
] \step in {1,...,0+cwsRadius/cwsStep} {
\fill[cws/rect, at y\cwsY/.try]
( \cwsX-cwsStep,-\cwsY) rectangle ( \cwsX,\cwsY)
(-\cwsX+cwsStep,-\cwsY) rectangle (-\cwsX,\cwsY);
\draw[step=cwsStep, cws/grid, at y\cwsY/.try]
( \cwsX-cwsStep,-\cwsY) grid ( \cwsX,\cwsY)
(-\cwsX+cwsStep,-\cwsY) grid (-\cwsX,\cwsY);
}
\draw[radius=cwsRadius,cws/circle] circle[];
\endscope
}
\begin{document}
\begin{tikzpicture}[column sep=5mm, row sep=5mm]
\matrix{
\tikzcirclewithsquares[]
& \tikzcirclewithsquares[circle/.append style=thick, outside]
\\
\tikzcirclewithsquares[radius=5, step=.5, rect/.style=green, outside]
& \tikzcirclewithsquares[radius=7.5, rect/.style=path only, step/.evaluated=abs(random)]
\\};
\end{tikzpicture}
\end{document}
输出
答案2
改编
- 设定范围为
{-10,...,10}
- 我添加了一个参数
\radius
- 用于
++(1,1)
指定矩形的大小,而不必重复原点坐标 - 扩展条件来检查所有 4 个角:
\pgfmathparse{
(\x+1)^2 + (\y+1)^2 <= \radius^2 &&
(\x+1)^2 + (\y)^2 <= \radius^2 &&
(\x)^2 + (\y+1)^2 <= \radius^2 &&
(\x)^2 + (\y)^2 <= \radius^2
}
- 或更短的版本:
max( (\x)^2, (\x+1)^2 ) + max( (\y)^2, (\y+1)^2 ) <= \radius^2
结果
代码
\documentclass[tikz, margin=2mm]{standalone}
\begin{document}
\begin{tikzpicture}
\def\radius{10}
\foreach \x in {-\radius,...,\radius} {
\foreach \y in {-\radius,...,\radius} {
\pgfmathparse{
(\x+1)^2 + (\y+1)^2 <= \radius^2 &&
(\x+1)^2 + (\y)^2 <= \radius^2 &&
(\x)^2 + (\y+1)^2 <= \radius^2 &&
(\x)^2 + (\y)^2 <= \radius^2
} %Condition of squares to stay inside the circle.
%This circle is translated to make it work.
\ifnum\pgfmathresult=1
\filldraw[fill=blue!50] (\x,\y) rectangle ++(1,1); %Colouring the squares
\fi
}
}
\draw (0,0) circle [radius=\radius]; %Circle
\end{tikzpicture}
\end{document}
扩大
为了使其更有趣并且不完全对称,您可以向矩形添加一些 x 和 y 偏移(参数\squaresXshift
和\squaresYshift
在 [0,1] 中)。
代码
\documentclass[tikz, margin=2mm]{standalone}
\begin{document}
\begin{tikzpicture}
\def\radius{6}
\def\squaresXshift{.3}
\def\squaresYshift{.1}
\foreach \x [evaluate=\x as \xp using {\x+\squaresXshift}] in {-\radius,...,\radius} {
\foreach \y [evaluate=\y as \yp using {\y+\squaresYshift}] in {-\radius,...,\radius} {
\pgfmathparse{
(\xp+1)^2 + (\yp+1)^2 <= \radius^2 &&
(\xp+1)^2 + (\yp)^2 <= \radius^2 &&
(\xp)^2 + (\yp+1)^2 <= \radius^2 &&
(\xp)^2 + (\yp)^2 <= \radius^2
} %Condition of squares to stay inside the circle.
%This circle is translated to make it work.
\ifnum\pgfmathresult=1
\filldraw[fill=blue!50] (\xp,\yp) rectangle ++(1,1); %Colouring the squares
\fi
}
}
\draw (0,0) circle [radius=\radius]; %Circle
\end{tikzpicture}
\end{document}
结果
答案3
由于对称性,有两种选择:要么圆心与正方形的角重合,要么与正方形的中心重合。先验地不清楚哪种选择会获胜。然而,简单的计算就能揭示哪种选择更有可能获胜。
事实证明,两种选择都可以获胜(尽管第一种选择更为常见)。
这是带有示例的代码。
\documentclass{article}
\usepackage[fleqn]{mathtools}
\usepackage{enumitem}
\usepackage{cleveref}
\usepackage{geometry}
\usepackage{tikz}
\usepackage{xfp}
\newlist{options}{enumerate}{1}
\setlist[options]{label=\roman*.,ref=\roman*}
\crefname{optionsi}{option}{options}
\begin{document}
Due to the symmetry of the problem, there are only two options: the center of the circle coincides with
\begin{options}
\item the corner of one of the squares\label{option1}, or
\item the center of one of the squares\label{option2}.
\end{options}
\begin{figure}[htb]
\centering\begin{tikzpicture}[declare function={R=2.5;phi=15;}]
\draw circle[radius=R];
\draw (0,0) -- node[above]{$R$} (phi:R) -- node[right]{$b=\begin{dcases}
a & (\text{\cref{option1}}) \\
\frac{a}{2}& (\text{\cref{option2}})
\end{dcases}$} ({cos(phi)*R},0) -- node[below]{$R\sqrt{1-(b/R)^2}$} cycle;
\end{tikzpicture}
\caption{Setup.}
\label{fig:setup}
\end{figure}
Call the edge length of the square $a$ and the radius of the circle $R$. The requirement is then that $a$ (see \Cref{fig:setup}) fulfills
\begin{align}
R\sqrt{1-\frac{a^2}{R^2}}&\ge n\,a\,,\tag{\text{\cref{option1}}}\\
R\sqrt{1-\frac{a^2}{4R^2}}&\ge (n+\tfrac{1}{2})\,a\,.\tag{\text{\cref{option2}}}
\end{align}
In both cases, $n$ denotes the number of squares which are entirely right of the center. Therefore,
\begin{equation}
n=\begin{dcases}
\left\lfloor \frac{R}{a}\sqrt{1-(a/R)^2}\right\rfloor\,,&(\text{\cref{option1}})\\
\left\lfloor \frac{R}{a}\sqrt{1-(a/2R)^2}-\frac{1}{2}\right\rfloor\,.&(\text{\cref{option2}})
\end{dcases}\label{eq:n}
\end{equation}
Unfortunately, if we know $n$, it is not obvious what the total number of squares, $N$, is. However, it appears reasonable to assume that it scales with the square of the number of squares in the widest row,
\begin{equation}
N\sim \begin{dcases}
4n^2\,,&(\text{\cref{option1}})\\
(2n+1)^2\,.&(\text{\cref{option2}})
\end{dcases} \label{eq:N}
\end{equation}
We now can fill the circle with square depending on which option leads to the larger $N$.
\begingroup
\def\R{6}
\foreach \ff in {1,...,7}
{\clearpage\begin{tikzpicture}
\pgfmathsetmacro{\a}{\R*exp(-0.5*\ff)}
\pgfmathtruncatemacro{\ni}{\fpeval{floor(\R*sqrt(1-\a*\a/(\R*\R))/\a)}} % this locally overwrites the macro \ni
\pgfmathtruncatemacro{\nii}{\fpeval{floor(\R*sqrt(1-\a*\a/(\R*\R))/\a-0.5)}}
\pgfmathtruncatemacro{\Ni}{\fpeval{4*\ni*\ni}}
\pgfmathtruncatemacro{\Nii}{\fpeval{(2*\nii+1)^2}}
\draw circle[radius=\R] (90:\R)node[above]{$a=\a$}
(-90:\R) node[below]{\ifnum\Ni>\Nii\relax
\cref{option1} wins: $n=\ni$\else
\cref{option2} wins: $n=\nii$
\fi};
\ifnum\Ni>\Nii\relax
\foreach \Y in {1,...,\ni}
{\pgfmathtruncatemacro{\nx}{floor(\R*sqrt(1-(\a*\Y)^2/(\R*\R))/\a)}
\foreach \X in {1,...,\nx}
{\draw (\X*\a,\Y*\a) rectangle ++ (-\a,-\a)
(-\X*\a,\Y*\a) rectangle ++ (\a,-\a)
(-\X*\a,-\Y*\a) rectangle ++ (\a,\a)
(\X*\a,-\Y*\a) rectangle ++ (-\a,\a); }}
\else
\foreach \Y in {1,...,\nii}
{\draw ({0.5*\a},{(\Y+0.5)*\a}) rectangle ++ (-\a,-\a)
({-(\Y+0.5)*\a},{0.5*\a}) rectangle ++ (\a,-\a)
({(\Y+0.5)*\a},{0.5*\a}) rectangle ++ (-\a,-\a)
({0.5*\a},{-(\Y+0.5)*\a}) rectangle ++ (-\a,\a);
\pgfmathtruncatemacro{\nx}{floor(\R*sqrt(1-(\a*\Y)^2/(\R*\R))/\a-0.5)-1}
\ifnum\nx>0\relax
\foreach \X in {1,...,\nx}
{\draw ({(\X+0.5)*\a},{(\Y+0.5)*\a}) rectangle ++ (-\a,-\a)
({-(\X+0.5)*\a},{(\Y+0.5)*\a}) rectangle ++ (\a,-\a)
({-(\X+0.5)*\a},{-(\Y+0.5)*\a}) rectangle ++ (\a,\a)
({(\X+0.5)*\a},{-(\Y+0.5)*\a}) rectangle ++ (-\a,\a);
}
\fi}
\fi
\end{tikzpicture}\par}
\endgroup
\end{document}