将不同图片中的节点相互对齐(绘制七巧板碎片)

将不同图片中的节点相互对齐(绘制七巧板碎片)

我使用以下代码,修改自这个帖子,将七巧板碎片相互对齐。

\documentclass[10pt,a4paper]{article}
\usepackage{geometry}
\geometry{a4paper, left=10mm, right=10mm, top=10mm, bottom=10mm}
\usepackage{verbatim}
\usepackage{tikz}
\pgfmathsetmacro{\inc}{3}
\pgfmathsetmacro{\lwidth}{.1mm}
\tikzset{
  big trianglea/.pic={
  \path[pic actions] (0,0) node (tbal){} -- (2,0) node (tbar){b} -- (2,2) node (tbat){} -- cycle;
  },
  big triangleb/.pic={
  \path[pic actions] (0,0) node (tbbl){} -- (2,0) node (tbbr){\textcolor {green}x} -- (2,2) node (tbbt){} -- cycle;
  },
  medium triangle/.pic={
    \path[pic actions] (0,0) node (tml){} -- (1,1) node (tmt){} -- (2,0) node (tmr){} -- cycle;  
  },
  square/.pic={
    \path[pic actions] (0,0) node (sdl){c} -- (1,0) node (sdr){} -- (1,1) node (sur){} -- (0,1) node (sul){} -- cycle;
  },
  small trianglea/.pic={
    \path[pic actions] (0,0) node (tsal){} -- (1,0) node (tsar){} -- (1,1) node (tsat){} -- cycle;
  },
  small triangleb/.pic={
    \path[pic actions] (0,0) node (tsbl){} -- (1,0) node (tsbr){} -- (1,1) node (tsbt){} -- cycle;
  },
  parallelogram/.pic={
    \path[pic actions] (0,0) node (padl){} -- (1,0) node (padr){} -- (2,1) node (paur){} -- (1,1) node (paul){} -- cycle;
  },
  parallelogramr/.pic={%to flip horizontally
    \path[pic actions] (0,0) node (prdl){a} -- (1,0) node (prdr){} -- (2,-1) node (prur){} -- (1,-1) node (prul){} -- cycle;
  }
}
\tikzset{
  tangram puzzle/.style={
    fill=black,
    draw=black,
    line width=\lwidth
  },
  tangram solution/.style={
      fill=white,%black
    draw=red,%black
    line width=\lwidth
  },   
  tangram/.style={
  transform shape,
    %tangram puzzle
    tangram solution
  }
}
\begin{document}
\begin{tikzpicture}[scale=\inc]
\pic[tangram,rotate=-63.44] at (0,0) {parallelogramr};
\pic[tangram,rotate=0] at (-.542,-3.236) {square};
\pic[tangram,rotate=-45] at (-1.4142,-3.238) {big trianglea};
\pic[tangram,rotate=135] at (1.4146,-6.068) {big triangleb};
\end{tikzpicture}
\end{document}

如您所见,需要经过多次尝试才能使pics彼此对齐。例如,the square位置对齐(-.542,-3.236)

是否可以轻松地相a certain node对于a certain pic对齐a node in another pic

例如使用代码将node (b)(在图片中trianglea)和node (k)(在图片中triangleb)相对于node (a)(位于图片中parallelogramr, )对齐node prdl[shift={(-90:6)}prdl.center]

在此处输入图片描述

答案1

如果您有带有必要节点的图片以供参考(您有),则使用库对齐各个部分并不困难calc。 就像这样:

\documentclass[border=2mm]{standalone}
\usepackage    {tikz}
\usetikzlibrary{calc}


\begin{document}
\begin{tikzpicture}
\tikzset
{%
  big triangle/.pic={%
    \path[pic actions] (0,0) node (-A) {} -- ({0.5*sqrt(2)},0)  node (-B) {} -- (0,{0.5*sqrt(2)}) node (-C) {} -- cycle;},
  medium triangle/.pic={%
    \path[pic actions] (0,0) node (-A) {} -- (0.5,0) node (-B) {} -- (0,0.5) node (-C) {} -- cycle;},
  small triangle/.pic={%
    \path[pic actions] (0,0) node (-A) {} -- ({0.25*sqrt(2)},0) node (-B) {} -- (0,{0.25*sqrt(2)}) node (-C) {} -- cycle;},
  square/.pic={%
    \path[pic actions] (0,0) node (-A) {} -- ({0.25*sqrt(2)},0) node (-B) {} -- ({0.25*sqrt(2)},{0.25*sqrt(2)}) node (-C) {} --
                       (0,{0.25*sqrt(2)}) node (-D) {} -- cycle;},
  parallelogram/.pic={%
    \path[pic actions] (0,0) node (-A) {} -- (0.5,0) node (-B) {} --++ (0.25,0.25) node (-C) {} --++
                       (-0.5,0) node (-D) {} -- cycle;},
  bt1/.style={% big triangle 1
    very thin,draw=black,fill=green!50!black,line cap=round,line join=round},
  bt2/.style={% big triangle 2
    very thin,draw=black,fill=red,line cap=round,line join=round},
  mt/.style={% medium triangle
    very thin,draw=black,fill=orange,line cap=round,line join=round},
  st1/.style={% small triangle 1
    very thin,draw=black,fill=brown,line cap=round,line join=round},
  st2/.style={% small triangle 2
    very thin,draw=black,fill=blue!50!black,line cap=round,line join=round},
  sq/.style={% square
    very thin,draw=black,fill=yellow,line cap=round,line join=round},
  pr/.style={% parallelogram
    very thin,draw=black,fill=blue,line cap=round,line join=round},
}
% tangram
\pic[bt1,rotate= 45] (BT1)                           {big triangle};
\pic[bt2,rotate=135] (BT2)                           {big triangle};
\pic[mt ,rotate= 90] (MT) at (BT1-B|-BT2-C)          {medium triangle};
\pic[st1,rotate=-45]      at ($(BT1-A)!0.5!(BT1-B)$) {small triangle};
\pic[sq ,rotate=-45]                                 {square};
\pic[st2,rotate=225]                                 {small triangle};
\pic[pr]                  at (BT2-C)                 {parallelogram};
% first monk
\pic[mt ,rotate= 90] (M1) at (2,-0.5)                        {medium triangle};
\pic[bt1,rotate=135] (M2) at (M1-B)                          {big triangle};
\pic[bt2,rotate=-45] (M3) at (M2-B)                          {big triangle};
\pic[st1,rotate=-45] (M4) at ($(M2-B)+(225:{0.25*sqrt(2)})$) {small triangle};
\pic[sq]             (M5) at ($(M3-C)-({0.125*sqrt(2)},0)$)  {square};
\pic[st2,rotate=225]      at ($(M5-C)!0.5!(M5-D)+(0,0.25)$)  {small triangle};
\pic[pr]                  at ($(M2-B)-(0.5,0)$)              {parallelogram};
% second monk
\pic[mt]             (N1) at (3,-0.5)                                           {medium triangle};
\pic[st1,rotate= 90]      at ($(N1-A)!0.5!(N1-B)-(0,{0.25*sqrt(2)})$)           {small triangle};
\pic[bt1,rotate=180] (N2) at ($(N1-B)+(0,{0.5*sqrt(2)})$)                       {big triangle};
\pic[bt2,rotate=450] (N3 )at (N2-A)                                             {big triangle};
\pic[sq]             (N4) at ($(N3-B)-({0.125*sqrt(2)},0)$)                     {square};
\pic[st2,rotate=225]      at ($(N4-C)!0.5!(N4-D)+(0,0.25)$)                     {small triangle};
\pic[pr]                  at ($(N3-B)!0.5!(N3-C)-(0.5,0)-(45:{0.125*sqrt(2)})$) {parallelogram};
% OP figure (candle?)
\pic[bt1,rotate=225] (P1) at (5,0)                                     {big triangle};
\pic[bt2,rotate= 45] (P2) at (P1-A)                                    {big triangle};
\pic[sq]             (P3) at ($(P2-B)!0.5!(P2-C)-({0.125*sqrt(2)},0)$) {square};
\pic[pr,rotate={atan(3)}] at ($(P3-C)!0.5!(P3-D)$)                     {parallelogram};
\end{tikzpicture}
\end{document}

编辑:这是另一种方法。我想说这是一种更好的方法。它有更多的代码(更多行),但我认为它更清晰。

我在 s 中添加了锚点pic(所有顶点和所有边中点)。我仍然使用该calc库来放置所有坐标。我按照 OP 的要求更改了比例。此外,我只pic为三角形创建了一个,带有一个大小参数。这是新代码:

\documentclass[border=2mm]{standalone}
\usepackage    {tikz}
\usetikzlibrary{calc}

\tikzset
{%
  pics/triangle/.style n args={3}{% name, anchor, size (1,2,3)
    code={%
    \pgfmathsetmacro\l{0.5*pow(sqrt(2),#3+1)}% cathetus length
    \coordinate (A-aux) at (0,0);
    \coordinate (B-aux) at (\l,0);
    \coordinate (C-aux) at (0,\l);
    \coordinate (D-aux) at (0.5*\l,0);
    \coordinate (E-aux) at (0.5*\l,0.5*\l);
    \coordinate (F-aux) at (0,0.5*\l);
    \foreach\i in {A,...,F}
      \coordinate (#1-\i) at ($(\i-aux)-(#2-aux)$);
    \path[pic actions] (#1-A) -- (#1-B) -- (#1-C) -- cycle;
    }},
  pics/square/.style 2 args={% name, anchor
    code={%
    \pgfmathsetmacro\l{1}% edge length
    \coordinate (A-aux) at (0,0);
    \coordinate (B-aux) at (\l,0);
    \coordinate (C-aux) at (\l,\l);
    \coordinate (D-aux) at (0,\l);
    \coordinate (E-aux) at (0.5*\l,0);
    \coordinate (F-aux) at (\l,0.5*\l);
    \coordinate (G-aux) at (0.5*\l,\l);
    \coordinate (H-aux) at (0,0.5*\l);
    \foreach\i in {A,...,H}
      \coordinate (#1-\i) at ($(\i-aux)-(#2-aux)$);
    \path[pic actions] (#1-A) -- (#1-B) -- (#1-C) -- (#1-D) -- cycle;
    }},
  pics/parallelogram/.style 2 args={% name, anchor
    code={%
    \pgfmathsetmacro\l{sqrt(2)}% big edge length
    \coordinate (A-aux) at (0,0);
    \coordinate (B-aux) at (\l,0);
    \coordinate (C-aux) at (1.5*\l,0.5*\l);
    \coordinate (D-aux) at (0.5*\l,0.5*\l);
    \coordinate (E-aux) at (0.5*\l,0);
    \coordinate (F-aux) at (1.25*\l,0.25*\l);
    \coordinate (G-aux) at (\l,0.5*\l);
    \coordinate (H-aux) at (0.25*\l,0.25*\l);
    \foreach\i in {A,...,H}
      \coordinate (#1-\i) at ($(\i-aux)-(#2-aux)$);
    \path[pic actions] (#1-A) -- (#1-B) -- (#1-C) -- (#1-D) -- cycle;
    }},
  tangram/.style={%
    very thin,draw,line cap=round,line join=round},
  bt1/.style={% big triangle 1
    tangram,fill=red},
  bt2/.style={% big triangle 2
    tangram,fill=green!50!black},
  mt/.style={% medium triangle
    tangram,fill=orange},
  st1/.style={% small triangle 1
    tangram,fill=brown},
  st2/.style={% small triangle 2
    tangram,fill=blue!50!black},
  sq/.style={% square
    tangram,fill=yellow},
  pr/.style={% parallelogram
    tangram,fill=blue},
  solution/.style={%
    tangram,draw=red,fill=white},
  puzzle/.style={%
    tangram,fill=black}
}

\begin{document}
\begin{tikzpicture}
% tangram
\pic[bt1,rotate=135]           {triangle     ={T1}{C}{3}};
\pic[bt2,rotate= 45] at (T1-B) {triangle     ={T2}{C}{3}};
\pic[st1,rotate=-45] at (T2-B) {triangle     ={T3}{C}{1}};
\pic[mt ,rotate= 90] at (T3-B) {triangle     ={T4}{B}{2}};
\pic[st2,rotate=225] at (T1-A) {triangle     ={T5}{A}{1}};
\pic[sq ,rotate=-45] at (T1-A) {square       ={T6}{A}};
\pic[pr            ] at (T1-C) {parallelogram={T7}{A}};
% first monk
\pic[mt ,rotate= 90] at (5 ,0) {triangle     ={M1}{C}{2}};
\pic[bt1,rotate=-45] at (M1-B) {triangle     ={M2}{B}{3}};
\pic[bt2,rotate=135] at (M1-C) {triangle     ={M3}{C}{3}};
\pic[st1,rotate=-45] at (M2-A) {triangle     ={M4}{C}{1}};
\pic[sq            ] at (M2-C) {square       ={M5}{E}};
\pic[st2,rotate=225] at (M5-G) {triangle     ={M6}{E}{1}};
\pic[pr            ] at (M3-B) {parallelogram={M7}{B}};
% second monk
\pic[mt            ] at (9 ,0) {triangle     ={N1}{A}{2}};
\pic[bt1,rotate=180] at (N1-B) {triangle     ={N2}{C}{3}};
\pic[bt2,rotate= 90] at (N2-A) {triangle     ={N3}{A}{3}};
\pic[st1,rotate= 90] at (N1-D) {triangle     ={N4}{B}{1}};
\pic[sq            ] at (N3-B) {square       ={N5}{E}};
\pic[st2,rotate=225] at (N5-G) {triangle     ={N6}{E}{1}};
\pic[pr            ] at (N3-E) {parallelogram={N7}{F}};
% OP figure (candle?)
\pgfmathsetmacro\a{atan(3)} % rotation angle for the parallelogram
\pic[bt2,rotate=225] at (13,0) {triangle     ={P1}{B}{3}};
\pic[bt1,rotate= 45] at (P1-A) {triangle     ={P2}{A}{3}};
\pic[sq            ] at (P2-E) {square       ={P3}{E}};
\pic[pr ,rotate= \a] at (P3-G) {parallelogram={P4}{A}};
\end{tikzpicture}
\end{document}

两段代码渲染出来的图像基本上是相同的:

在此处输入图片描述

编辑2:我按照原帖的要求添加了两种谜题和解决方案的样式,但它们并未在上图中使用。

答案2

经过深思熟虑,我觉得我更喜欢 Juan 的回答,但正如我所说,我认为我的penrose软件包可以提供帮助,那么这里是将其用于七巧板的起点。它做得很好的是将一个图块与另一个图块沿边缘对齐。它做得不好的地方是允许该对齐位于边缘的任意点。该软件包主要设计用于边缘完全匹配的平铺,而在七巧板软件包中,这不是必需的。尽管如此,仍可以调整 penrose 软件包的工具,或对其进行轻微调整,以使它们以更直观的方式工作。

以下代码定义了图块,然后使用对齐将它们组合成标准正方形。这在 MikTeX 和 TeXLive 中均可行,但可能需要两者都保持最新(特别是,MikTeX 可能不会发现 penrose 包需要更新,因为它是一个 tikz 库,而不是实际的 package0)。

有关对齐工作原理的解释,请参阅 penrose 包文档。

\documentclass{article}
%\url{https://tex.stackexchange.com/q/603673/86}
\usepackage{tikz}
\usetikzlibrary{penrose}


\DefineTile{big triangle}{1 1 1}
{
 {0,0}
 {2,0}
 {2,2}
}

\DefineTile{medium triangle}{1 1 1}
{
 {0,0}
 {2,0}
 {1,1}
}

\DefineTile{small triangle}{1 1 1}
{
 {0,0}
 {1,0}
 {1,1}
}

\DefineTile{parallelogram}{1 1 1 1}
{
  {0,0}
  {1,0}
  {2,1}
  {1,1}
}

\DefineTile{square}{1 1 1 1}
{
  {0,0}
  {1,0}
  {1,1}
  {0,1}
}


\tikzset{clone Penrose side path={1}{a}}
\BakePenroseTile{big triangle}
\BakePenroseTile{medium triangle}
\BakePenroseTile{small triangle}
\BakePenroseTile{parallelogram}
\BakePenroseTile{square}


\begin{document}

\begin{tikzpicture}[every Penrose tile/.style={draw=black, fill=green}]
\pic[big triangle, name = A];
\pic[big triangle, name = B, align with=A along 12 using 1];
\pic[small triangle, name = C, align with=A along 11 using 2];
\pic[square, name = D, align with=C along 11 using 1];
\pic[small triangle, name = E, align with=D along 13 using 2];
\pic[parallelogram, name = F, align with=E along 13 using 2];
\pic[medium triangle, name=G, align with=D along 12 using 1];
\end{tikzpicture}


\end{document}

结果:

七巧板自动对齐

相关内容