1

I want to reflect the black filled polygons. With this solution, I can't fill the symmetric polygons. Would you have a tip to have this done ?

\documentclass{report}
\usepackage{tikz}
\usetikzlibrary{calc}

\tikzset{reflect at/.style args={#1--#2}{to path={%
            ($2*($(#1)!(\tikztostart)!(#2)$)-(\tikztostart)$)
            -- ($2*($(#1)!(\tikztotarget)!(#2)$)-(\tikztotarget)$)
}}}

\begin{document}
\begin{tikzpicture}[scale=1]
\draw [very thin, gray] (2,1) grid (12,9);

\node (X) at (7,2) {};
\node (Y) at (7,8) {};

\draw[color=red,very thick](X.center)--(Y.center);

\begin{scope}
\foreach \point [count=\i] in {{(4,2)},{(3,2)},{(3,4)},{(4,4)}} {
\node (A\i) at \point {};
}
\draw[fill=black] (A1.center)--(A2.center)--(A3.center)--(A4.center)--cycle;
\draw[thick,reflect at=X--Y] (A1) to (A2) (A2) to (A3) (A3) to (A4) (A4) to (A1);
\end{scope}

\begin{scope}
\foreach \point [count=\i] in {{(3,6)},{(4,6)},{(4,8)},{(3,8)}} {
    \node (A\i) at \point {};
}
\draw[fill=black] (A1.center)--(A2.center)--(A3.center)--(A4.center)--cycle;
\draw[thick,reflect at=X--Y] (A1) to (A2) (A2) to (A3) (A3) to (A4) (A4) to (A1);
\end{scope}

\begin{scope}
\foreach \point [count=\i] in {{(5,5)},{(5,7)},{(7,5)},{(7,3)}} {
    \node (A\i) at \point {};
}
\draw[fill=black] (A1.center)--(A2.center)--(A3.center)--(A4.center)--cycle;
\draw[thick,reflect at=X--Y] (A1) to (A2) (A2) to (A3) (A3) to (A4) (A4) to (A1);
\end{scope}

\begin{scope}
\foreach \point [count=\i] in {{(9,5)},{(9,7)},{(10,8)},{(10,6)}} {
    \node (A\i) at \point {};
}
\draw[fill=black] (A1.center)--(A2.center)--(A3.center)--(A4.center)--cycle;
\draw[thick,reflect at=X--Y] (A1) to (A2) (A2) to (A3) (A3) to (A4) (A4) to (A1);
\end{scope}

\begin{scope}
\foreach \point [count=\i] in {{(10,4)},{(10,6)},{(11,6)},{(11,4)}} {
    \node (A\i) at \point {};
}
\draw[fill=black] (A1.center)--(A2.center)--(A3.center)--(A4.center)--cycle;
\draw[thick,reflect at=X--Y] (A1) to (A2) (A2) to (A3) (A3) to (A4) (A4) to (A1);
\end{scope}
\end{tikzpicture}
\end{document}

Thank you

jadou
  • 213
  • The mirrored path is collection of segments that cannot be filled. You cannot easily change this because of the way you mirror things with to path. You could use Paul Gaborit's solution instead. –  May 01 '20 at 15:10

1 Answers1

1

There have been various proposals to do that. Assuming that we want to keep our fingers/paws away from transform canvas, one of the most directly applicable answer seems to be Paul Gaborit's solution.

However, I take the question as challenge to hack to path to yield the desired result. To this end, let us first recall why the above code does not allow fills. You decompose the contour into disconnected little segments, which cannot be filled. If you did not, the to path hack wouldn't work. So what can one do? One ad hoc possibility is to employ execute at end to. The downside is that the hack draws the polygon more than once, and in the earlier incarnations only partially (which one could fix if the user is ready to supply the number of corners), on the bright side it turns the collection of disconnected paths into a polygon with nice line joins. The fill style etc. is stored in fancy reflect/.style.

\documentclass{report}
\usepackage{tikz}
\usetikzlibrary{calc}
\newcounter{reflectedcoord}
\tikzset{fancy reflect at/.style args={#1--#2}{ini reflect,to path={%
            ($2*($(#1)!(\tikztostart)!(#2)$)-(\tikztostart)$)
            \pgfextra{\stepcounter{reflectedcoord}}%
            coordinate(reflectedcoord-\number\value{reflectedcoord})
            -- ($2*($(#1)!(\tikztotarget)!(#2)$)-(\tikztotarget)$)
},execute at end to={%\typeout{\number\value{reflectedcoord}}
\ifnum\value{reflectedcoord}>1
\path[fancy reflect,polygon through={reflectedcoord-1,reflectedcoord-...,reflectedcoord-\number\value{reflectedcoord}}];
\fi}},ini reflect/.code={\setcounter{reflectedcoord}{0}},
polygon through/.style={insert path={
    plot[samples at={#1}] (\x) -- cycle}},
    fancy reflect/.style={fill=red,draw,thick}}

\begin{document}
\begin{tikzpicture}[scale=1]
\draw [very thin, gray] (2,1) grid (12,9);

\node (X) at (7,2) {};
\node (Y) at (7,8) {};

\draw[color=red,very thick](X.center)--(Y.center);

\begin{scope}
\foreach \point [count=\i] in {{(4,2)},{(3,2)},{(3,4)},{(4,4)}} {
\node (A\i) at \point {};
}
\draw[fill=black] (A1.center)--(A2.center)--(A3.center)--(A4.center)--cycle;
\draw[fancy reflect at=X--Y] (A1) to (A2) (A2) to (A3) (A3) to (A4) (A4) to (A1);
\end{scope}

\begin{scope}
\foreach \point [count=\i] in {{(3,6)},{(4,6)},{(4,8)},{(3,8)}} {
    \node (A\i) at \point {};
}
\draw[fill=black] (A1.center)--(A2.center)--(A3.center)--(A4.center)--cycle;
\draw[fancy reflect at=X--Y] (A1) to (A2) (A2) to (A3) (A3) to (A4) (A4) to (A1);
\end{scope}

\begin{scope}
\foreach \point [count=\i] in {{(5,5)},{(5,7)},{(7,5)},{(7,3)}} {
    \node (A\i) at \point {};
}
\draw[fill=black] (A1.center)--(A2.center)--(A3.center)--(A4.center)--cycle;
\draw[fancy reflect at=X--Y] (A1) to (A2) (A2) to (A3) (A3) to (A4) (A4) to (A1);
\end{scope}

\begin{scope}
\foreach \point [count=\i] in {{(9,5)},{(9,7)},{(10,8)},{(10,6)}} {
    \node (A\i) at \point {};
}
\draw[fill=black] (A1.center)--(A2.center)--(A3.center)--(A4.center)--cycle;
\draw[fancy reflect at=X--Y] (A1) to (A2) (A2) to (A3) (A3) to (A4) (A4) to (A1);
\end{scope}

\begin{scope}
\foreach \point [count=\i] in {{(10,4)},{(10,6)},{(11,6)},{(11,4)}} {
    \node (A\i) at \point {};
}
\draw[fill=black] (A1.center)--(A2.center)--(A3.center)--(A4.center)--cycle;
\draw[fancy reflect at=X--Y] (A1) to (A2) (A2) to (A3) (A3) to (A4) (A4) to (A1);
\end{scope}
\end{tikzpicture}
\end{document}

enter image description here

As one can see, the line joins of the intermediate polygons cause some dismay (which one could turn off with line join=round, say). The cleaner solution is to let the user supply the number of corners because this also works with nontrivial opacities and so on.

\documentclass{report}
\usepackage{tikz}
\usetikzlibrary{calc}
\newcounter{reflectedcoord}
\tikzset{fancy reflect at/.style args={#1--#2}{ini reflect,to path={%
            ($2*($(#1)!(\tikztostart)!(#2)$)-(\tikztostart)$)
            \pgfextra{\stepcounter{reflectedcoord}}%
            coordinate(reflectedcoord-\number\value{reflectedcoord})
            -- ($2*($(#1)!(\tikztotarget)!(#2)$)-(\tikztotarget)$)
},execute at end to={%\typeout{\number\value{reflectedcoord}}
\ifnum\value{reflectedcoord}=\pgfkeysvalueof{/tikz/n reflect}
\path[fancy reflect,polygon through={reflectedcoord-1,reflectedcoord-...,reflectedcoord-\number\value{reflectedcoord}}];
\fi}},ini reflect/.code={\setcounter{reflectedcoord}{0}},
polygon through/.style={insert path={
    plot[samples at={#1}] (\x) -- cycle}},
    fancy reflect/.style={fill=red,draw,thick},
    n reflect/.initial=4}

\begin{document}
\begin{tikzpicture}[scale=1]
\draw [very thin, gray] (2,1) grid (12,9);

\node (X) at (7,2) {};
\node (Y) at (7,8) {};

\draw[color=red,very thick](X.center)--(Y.center);

\begin{scope}
\foreach \point [count=\i] in {{(4,2)},{(3,2)},{(3,4)},{(4,4)}} {
\node (A\i) at \point {};
}
\draw[fill=black] (A1.center)--(A2.center)--(A3.center)--(A4.center)--cycle;
\draw[fancy reflect at=X--Y] (A1) to (A2) (A2) to (A3) (A3) to (A4) (A4) to (A1);
\end{scope}

\begin{scope}
\foreach \point [count=\i] in {{(3,6)},{(4,6)},{(4,8)},{(3,8)}} {
    \node (A\i) at \point {};
}
\draw[fill=black] (A1.center)--(A2.center)--(A3.center)--(A4.center)--cycle;
\path[fancy reflect at=X--Y] (A1) to (A2) (A2) to (A3) (A3) to (A4) (A4) to (A1);
\end{scope}

\begin{scope}
\foreach \point [count=\i] in {{(5,5)},{(5,7)},{(7,5)},{(7,3)}} {
    \node (A\i) at \point {};
}
\draw[fill=black] (A1.center)--(A2.center)--(A3.center)--(A4.center)--cycle;
\path[fancy reflect at=X--Y] (A1) to (A2) (A2) to (A3) (A3) to (A4) (A4) to (A1);
\end{scope}

\begin{scope}
\foreach \point [count=\i] in {{(9,5)},{(9,7)},{(10,8)},{(10,6)}} {
    \node (A\i) at \point {};
}
\draw[fill=black] (A1.center)--(A2.center)--(A3.center)--(A4.center)--cycle;
\path[fancy reflect at=X--Y] (A1) to (A2) (A2) to (A3) (A3) to (A4) (A4) to (A1);
\end{scope}

\begin{scope}
\foreach \point [count=\i] in {{(10,4)},{(10,6)},{(11,6)},{(11,4)}} {
    \node (A\i) at \point {};
}
\draw[fill=black] (A1.center)--(A2.center)--(A3.center)--(A4.center)--cycle;
\path[fancy reflect at=X--Y] (A1) to (A2) (A2) to (A3) (A3) to (A4) (A4) to (A1);
\end{scope}
\end{tikzpicture}
\end{document}

enter image description here

  • Many thanks, it's working great. Is there a way to fill directly the two polygons from the list of points (for the cases when the polygons have more than 4 edges) ? – jadou May 02 '20 at 09:22
  • @jadou Sorry, I do not understand the question. The above works with larger polygons, too, you need to set n reflect=5, say. –  May 02 '20 at 19:37