绘制鲁洛三角形

绘制鲁洛三角形

鲁洛三角形是一种宽度恒定的形状,有点像圆角等边三角形。

来自维基百科的鲁洛三角形

鲁洛三角形 - 维基百科,自由的百科全书

它可以像三集维恩图一样由三个圆圈相交形成。

来自 MathWorld 的鲁洛三角形

鲁洛三角形 -- 来自 Wolfram MathWorld

使用 TikZ、Asymptote 或某些可嵌入到 LaTeX 中的语言绘制鲁洛三角形的最佳方法是什么?也许通过绘制维恩图的三个圆圈并切掉其余部分?

答案1

这是一个小元帖子绘制一般函数鲁洛多边形. 解释如下。

prologues := 3;
outputtemplate := "%j%c.eps";

vardef reuleaux(expr n) = 
  for t=0 step 360/n until 359:
    1/2 up rotated t { left rotated (t+90/n) } .. { left rotated (t+270/n)} 
  endfor cycle enddef;

beginfig(1);
for i := 3 step 2 until 9:
  draw reuleaux(i) scaled 40i withcolor .6 red withpen pencircle scaled 1;
  draw fullcircle  scaled 40i withcolor .6 white;
endfor
endfig;    
end.

根据需要缩放、旋转、移动。其大小应适合缩放fullcircle到相同量。 在此处输入图片描述

每个角都是point路径的 ,因此如果要连接顶点,请连接 点0, 1, ..., n-1;如果想要每个圆弧的中点,请使用 点1/2, 3/2, ..., n-1/2,如下所示:

beginfig(2);
path t[];
for n := 3 upto 7:
  t[n] = reuleaux(n) scaled 60 shifted (75n,0);
  fill t[n] withcolor red+0.75green+0.2blue;
  draw for i = 0 upto n-1: point i     of t[n] -- endfor cycle withcolor .6 red;
  draw for i = 0 upto n-1: point i+1/2 of t[n] -- endfor cycle withcolor .6 blue;
endfor
endfig;

在此处输入图片描述

显然,您也可以挑选出要标记的点。

beginfig(3);
path t; t = reuleaux(3) scaled 90;
draw t withcolor .6 red;
dotlabel.top (btex $A$ etex, point 0 of t);
dotlabel.llft(btex $B$ etex, point 1 of t);
dotlabel.lrt (btex $C$ etex, point 2 of t);
endfig;

标记鲁洛三角形

解释

我对这个问题进行了几次修改,因为我对这个问题进行了更多的思考。使用了原始版本buildcycle和预定义的圆形路径,但它们并不是真正需要的。这里的最终版本是我所能做到的简单而正确的。

函数reuleaux(n)返回path一个n顶点由圆弧连接,圆弧的半径是相应正多边形最长对角线的长度。

要理解它的作用,首先考虑以下函数,该函数返回正多边形的路径,其中n顶点:

vardef polygon(expr n) = 
  for t=0 step 360/n until 359:
    up rotated t -- 
  endfor cycle enddef;

up扩展为(0,1),因此n=3 该函数扩展为

(0,1) -- (-0.866,-0.5) -- (0.866,-0.5) -- cycle

就像一个三边形的正多边形适合一个单位半径的圆一样。然而在 Metapost 中,预定义的fullcircle路径有单位直径为了保持一致性,最好将多边形缩小 1/2,

vardef polygon(expr n) = 
  for t=0 step 360/n until 359:
    1/2 up rotated t -- 
  endfor cycle enddef;

MP 中的优先规则意味着1/2 up扩展为(0,0.5)我们想要的。

现在我们有一个正多边形,可以容纳fullcircle,为了使它变成鲁洛多边形,我们必须将直线弯曲成以对顶点为中心的圆弧(或当n是偶数)。我们可以使用路径方向符号来实现这一点,并改为--允许..路径弯曲。

vardef reuleaux(expr n) = 
  for t=0 step 360/n until 359:
    1/2 up rotated t { left rotated (t+90/n) } .. { left rotated (t+270/n)} 
  endfor cycle enddef;

因为leftup rotated 90,所需的方向由所示的公式给出,你可以利用一些基本的几何知识来推导出来:

一些基本几何知识

如果你想让自己相信所得到的圆弧确实是圆形的,并且有正确的圆心,那么在上面画一个适当缩放和移动的圆。这种圆的半径将是多边形上最长对角线的长度——交流如上图所示 - 您可以使用length (point (n+1)/2 of r - point 0 of r)where找到它r=reuleaux(n)

应用

鲁洛三角形具有一些传统的几何图案,例如:

传统几何拼贴

我们可以像这样绘制:(如果有更好的平铺方法,请评论!)

beginfig(6);
  path t, ring; s := 10; 
  t = reuleaux(3) scaled s;
  ring = for i=0 upto 5: subpath(-1,1) of t shifted (0,s) rotated (i*60) .. endfor cycle;
  pair offset;
  for i=0 upto 5:
    dx := 0;
    for j=0 upto 13:
      offset := (3*s,0) rotated (30*(j mod 2*2-1));
      dx := dx + xpart offset;
      dy := 3*i*s + 1/2 ypart offset;
      draw ring shifted (dx,dy) withcolor (.5,.7,.9);
    endfor
  endfor
endfig;

这可能成为其他探索的基础。例如,只需改变的定义t即可t = reuleaux(2) scaled s产生这种相当奇妙的模式。

在此处输入图片描述

变化

如果您想要一个指向右而不是指向上的雷洛多边形,那么您只需将定义中的up和替换为和。leftrightup

vardef reuleaux(expr n) = 
  for t=0 step 360/n until 359:
    1/2 right rotated t { up rotated (t+90/n) } .. { up rotated (t+270/n)} 
  endfor cycle enddef;

beginfig(7);
  for n=3 upto 7:
     draw fullcircle  scaled 60 shifted (75n,0) withcolor .8 white;
     draw reuleaux(n) scaled 60 shifted (75n,0) withcolor .67 red;
  endfor
endfig;

这与普通 MP 稍微一致,因为这些形状的 0 点对应于零度旋转。它们看起来像这样:

在此处输入图片描述

我们还可以交换定义中的两个方向来生成所谓的反鲁洛多边形。

vardef antireuleaux(expr n) = 
  for t=0 step 360/n until 359:
    1/2 right rotated t { up rotated (t+270/n) } .. { up rotated (t+90/n)} 
  endfor cycle enddef;

在此处输入图片描述

正如你在下面看到的,这些反形状与以下形状相似,但又略有不同:内摆线曲線。

vardef hypocycloid(expr k) = 
  for t=0 step 1 until 360:
    point 0 of (fullcircle scaled (1/k) rotated (-t*k) 
                     shifted (1/2 right scaled (1-1/k))) rotated t --
  endfor cycle
enddef;

在此处输入图片描述

还可以将 Reuleaux 多边形的角弄圆,同时仍保留恒定宽度属性。这是一个生成圆形的函数,它采用了略微更通用的方法。第一个参数是边数,第二个参数是圆角半径占宽度的比例。

vardef polygon(expr n) = 
  for t=0 step 360/n until 359:
    1/2 right rotated t -- 
  endfor cycle 
enddef;

vardef rounded_reuleaux(expr n, s) = 
  save m, a, b, p; m := (n+1)/2;
  pair a,b; path p; p := polygon(n); 
  for i = 0 upto n-1:
    hide(
      a := point i   of p - point i+m of p; 
      b := point i+1 of p - point i+m of p;
    )
    point i   of p + s*unitvector(a) { up rotated angle a } .. 
    point i+1 of p + s*unitvector(b) { up rotated angle b } ..
  endfor cycle
enddef;

beginfig(8);
for n := 3 upto 7:
   fill rounded_reuleaux(n,1/6) scaled 60 shifted (85n,0) withcolor (1/2,3/4,5/6);
   draw reuleaux(n)             scaled 60 shifted (85n,0);
endfor

在此处输入图片描述

答案2

另一个 TikZ 解决方案,但这次,TikZ 完成了所有工作。您只需提供两个坐标(等边三角形的两个顶点),另一个顶点和半径就会自动计算。例如,下面的图像是使用

\Reuleaux{0,0}{2,0}
\Reuleaux[Dandelion]{0,0}{3,-2}

代码:

\documentclass[dvipsnames]{article}
\usepackage{tikz}
\usetikzlibrary{intersections,positioning,calc}

\newcommand\Reuleaux[3][Aquamarine]{%
\def\A{#2}
\def\B{#3}
\begin{tikzpicture}
\begin{scope}
\clip[name path global=c1] (\A) 
  let
  \p1 = ($ (\B) - (\A) $)
  in
  circle ({veclen(\x1,\y1)});
\clip[name path global=c2] (\B) 
  let
  \p1 = ($ (\B) - (\A) $)
  in
  circle ({veclen(\x1,\y1)});
\clip[name path global=c3] ($ (\A) ! .5 ! (\B) ! {sin(60)*2} ! 90:(\B) $) 
  let
  \p1 = ($ (\B) - (\A) $)
  in
  circle ({veclen(\x1,\y1)});
\fill[#1] (current bounding box.north west) rectangle (current bounding box.south east);
\end{scope}
\draw (\A) 
  let
  \p1 = ($ (\B) - (\A) $)
  in
  circle ({veclen(\x1,\y1)});
\draw (\B) 
  let
  \p1 = ($ (\B) - (\A) $)
  in
  circle ({veclen(\x1,\y1)});
\draw ($ (\A) ! .5 ! (\B) ! {sin(60)*2} ! 90:(\B) $) 
  let
  \p1 = ($ (\B) - (\A) $)
  in
  circle ({veclen(\x1,\y1)});
\fill [name intersections={of=c1 and c2,by={a,b}}]
  (a) circle (2pt) node[label=above:$A$] {};
\fill [name intersections={of=c2 and c3,by={c,d}}]
  (d) circle (2pt) node[label=left:$B$] {};
\fill [name intersections={of=c3 and c1,by={e,f}}]
  (f) circle (2pt) node[label=right:$C$] {};
\draw (a) -- (d) -- (f) -- cycle;
\end{tikzpicture}%
}

\begin{document}

\Reuleaux{0,0}{2,0}

\Reuleaux[Dandelion]{0,0}{3,-2}

\end{document}

在此处输入图片描述

如果仅要生成三角形,则可以从上述代码中抑制 \draw 命令:

\documentclass[dvipsnames]{article}
\usepackage{tikz}
\usetikzlibrary{intersections,positioning,calc}

\newcommand\Reuleaux[3][Aquamarine]{%
\def\A{#2}
\def\B{#3}
\begin{tikzpicture}
\begin{scope}
\clip[name path global=c1] (\A) 
  let
  \p1 = ($ (\B) - (\A) $)
  in
  circle ({veclen(\x1,\y1)});
\clip[name path global=c2] (\B) 
  let
  \p1 = ($ (\B) - (\A) $)
  in
  circle ({veclen(\x1,\y1)});
\clip[name path global=c3] ($ (\A) ! .5 ! (\B) ! {sin(60)*2} ! 90:(\B) $) 
  let
  \p1 = ($ (\B) - (\A) $)
  in
  circle ({veclen(\x1,\y1)});
\fill[#1] (current bounding box.north west) rectangle (current bounding box.south east);
\end{scope}
\fill [name intersections={of=c1 and c2,by={a,b}}]
  (a) circle (2pt) node[label=above:$A$] {};
\fill [name intersections={of=c2 and c3,by={c,d}}]
  (d) circle (2pt) node[label=left:$B$] {};
\fill [name intersections={of=c3 and c1,by={e,f}}]
  (f) circle (2pt) node[label=right:$C$] {};
\draw (a) -- (d) -- (f) -- cycle;
\end{tikzpicture}%
}

\begin{document}

\Reuleaux{0,0}{2,0}

\Reuleaux[Dandelion]{0,0}{3,-2}

\Reuleaux[Maroon]{-2,-2}{0,0}

\end{document}

在此处输入图片描述

答案3

使用 tkz-euclide

\documentclass{scrartcl}
\usepackage{tkz-euclide}
\usetkzobj{all}

\begin{document}
  \begin{tikzpicture}
    \tkzDefPoint(0,0){A}
    \tkzDefPoint(5,0){B}
    \tkzDefEquilateral(A,B)\tkzGetPoint{C}
    \tkzDrawPolygon[red](A,B,C)
    \tkzDrawArc[fill=gray!20](A,B)(C)
    \tkzDrawArc[fill=gray!20](B,C)(A)
    \tkzDrawArc[fill=gray!20](C,A)(B)
  \end{tikzpicture}
\end{document}

在此处输入图片描述

  \begin{tikzpicture}
    \tkzDefPoint(0,0){A}
    \tkzDefPoint(5,0){B}
    \tkzDefEquilateral(A,B)\tkzGetPoint{C}
    \tkzDrawPolygon[red](A,B,C)
    \begin{scope}
        \tkzSetUpLine[style=dashed,color=gray]
        \tkzDrawCircle(B,C)
        \tkzDrawCircle(A,B)
        \tkzDrawCircle(C,A)
    \end{scope}
    \tkzDrawArc[fill=gray!20](A,B)(C)
    \tkzDrawArc[fill=gray!20](B,C)(A)
    \tkzDrawArc[fill=gray!20](C,A)(B)
    \end{tikzpicture}

在此处输入图片描述

最后

\documentclass{scrartcl}
\usepackage{tkz-euclide}
\usetkzobj{all}

\begin{document}
  \begin{tikzpicture}
    \tkzDefPoint(0,0){A}
    \tkzDefPoint(5,0){B}
    \tkzDefEquilateral(A,B)\tkzGetPoint{C}
    \tkzFillSector[fill=gray!20](A,B)(C)
    \tkzFillSector[fill=gray!20](B,C)(A)
    \tkzFillSector[fill=gray!20](C,A)(B)
  \end{tikzpicture}   
\end{document}

在此处输入图片描述

备注:可以使用最后一个代码创建一个宏。

附件:使用 tikz 的最小代码是(基于 Mark Wibrow 的回答)

 \documentclass[tikz,border=5]{standalone}
   \begin{document}
    \tikz\draw[fill=blue!20] (0,0)
    \foreach \i in {1,2,3}{ arc (\i*120:\i*120+60:4)} ;
  \end{document}

在此处输入图片描述

答案4

根据 percusse 的建议,但在 Asymptote 中实现,不需要角度计算。关键是函数,它返回以从到arc(c, a, b)为中心的圆弧。(如果没有这样的圆弧,则它返回以从到线为中心的圆弧。)cabcac--b

还请注意使用&运算符连接具有公共端点的两个路径。

\documentclass[margin=10pt]{standalone}
\usepackage{asymptote}
\begin{document}
\begin{asy}
unitsize(3cm);
path triangle = scale(1/2)*polygon(3);
pair a = point(triangle, 0), b=point(triangle,1), c=point(triangle,2);
path releaux = arc(c=a, b, c) & arc(c=b, c, a) & arc(c=c, a, b) & cycle;
fill(releaux, gray);
draw(releaux);
\end{asy}
\end{document}

结果:

相关内容