6

I know how to draw each square separately, but I can't put them together as shown in the figure. enter image description here

benedito
  • 4,600

4 Answers4

11

Here is one possible solution that draws the gray rectangles, then draw the black rectangles and redraw inside (clipping is done by path picture) the first two rectangles in white.

\documentclass[tikz,border=7mm]{standalone}
\usetikzlibrary{calc}
\begin{document}
  \begin{tikzpicture}
    % the two gray rectangles
    \node[draw, fill=gray, minimum size=4cm, rotate=45] (A) at (0,0) {};
    \node[draw, fill=gray, minimum size=2cm, rotate=20] (C) at (5,.5) {};
    % the two black rectangles and the white rectangles clipped inside
    \node[draw, fill=black, minimum size=3cm, rotate=-20,
      path picture={
        \node[draw, fill=white, minimum size=4cm, rotate=45] at (A) {};
        \node[draw, fill=white, minimum size=2cm, rotate=20] at (C) {};
      }] at (3,1){};
    \node[draw, fill=black, minimum size=1cm, rotate=30,
      path picture={
        \node[draw, fill=white, minimum size=2cm, rotate=20] at (C) {};
      }] (D) at (6.2,0) {};
  \end{tikzpicture}
\end{document}

enter image description here

Note: Please the next time add a MWE in your question.

Kpym
  • 23,002
5

Didn't really need pics, but anyway the basic idea is to exploit the name path key from the intersections library so the paths only have to be specified once, and then do a bunch of clipping...

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{intersections}
\tikzset{use path/.code={
  \pgfextra{\csname tikz@intersect@path@name@#1\endcsname}%
}, 
square/.pic={code={
  \path  [pic actions, name path=square #1] 
    (-#1/2,-#1/2) rectangle ++(#1,#1);
}}}
\begin{document}
\begin{tikzpicture}[x=1em,y=1em]
\pic [fill=gray,  rotate=45]  at (0,0)   {square=11};
\pic [fill=black, rotate=-30] at (7,0)   {square=9};
\pic [fill=gray,  rotate=10]  at (14,-2) {square=7};
\pic [fill=black, rotate=30]  at (18,-5) {square=5};

\foreach \l/\r in {11/9, 9/7, 7/5}{
\begin{scope}
  \clip [use path=square \l]; \clip [use path=square \r];
  \fill [use path=square \l, white];
\end{scope}}
\foreach \s in {5, 7, 9, 11} \draw [use path=square \s];
\end{tikzpicture}
\end{document}

enter image description here

Mark Wibrow
  • 70,437
5

A low-complexity approach is to use two paths for clipping the white areas in the black rectangles. Here, we simply construct the four rectangles (A), (B), (C), (D) with arguments: [minimum size=#1,rotate=#2,fill=#3]. Then, we set a path the same as node(A) by:

\path[clip] (A.45)--(A.135)--(A.-135)--(A.-45)--cycle;

because a node cannot be used for clipping. This is used to construct the white area in rectangle (B). Next, we set a path the same as node(C) by:

\path[clip] (C.45)--(C.135)--(C.-135)--(C.-45)--cycle;

and use it for clipping the remaining two white areas in rectangles (B) and (D).

\documentclass[border=1pt,tikz]{standalone}
\begin{document}

\begin{tikzpicture}[blk/.style args={#1,#2,#3}{draw,minimum size=#1,rotate=#2,fill=#3}] 

\node(A)[blk={4cm,45,gray}]at(0,0){};
\node(B)[blk={3cm,70,black}]at(3,1){};
\node(C)[blk={2cm,20,gray}]at(5,.5){};
\node(D)[blk={1cm,30,black}]at(6.2,0){};

\begin{scope}
\path[clip] (A.45)--(A.135)--(A.-135)--(A.-45)--cycle;
\node[blk={3cm,70,white}]at(3,1){};
\end{scope}

\begin{scope}
\path[clip] (C.45)--(C.135)--(C.-135)--(C.-45)--cycle;
\node[blk={3cm,70,white}]at(3,1){};
\node[blk={1cm,30,white}]at(6.2,0){};
\end{scope}

\end{tikzpicture}

\end{document}

enter image description here

AboAmmar
  • 46,352
  • 4
  • 58
  • 127
1

An alternative approach in Metapost.

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

beginfig(1);

u := 1.6mm;
defaultfont := "phvr8r";
path A, B, C, D;

A = unitsquare scaled  5u rotated  30;
B = unitsquare scaled  7u rotated  20 shifted (-6u,1u);
C = unitsquare scaled  9u rotated  80 shifted (-7u,1u);
D = unitsquare scaled 11u rotated  50 shifted (-18u,-3u);


fill A withcolor .3 white; 
fill B withcolor .8 white;
fill C withcolor .3 white;
fill D withcolor .8 white;

unfill buildcycle(A,B);
unfill buildcycle(B,C);
unfill buildcycle(C,D);

draw A; draw B; draw C; draw D;

label.urt("5", point 1.5 of A);
label.bot("7", point 0.3 of B);
label.top("9", point 1.5 of C);
label.ulft("11", point 2.5 of D);

endfig;
end.

enter image description here

Note that if the start (point 0 of ...) of any of the squares falls inside any of the others, then buildcycle fails to find the correct overlap for the reasons explained in my answer to this question.

Thruston
  • 42,268