4

Following this answer, I need to:

  1. draw a horizontal line between point a and its scope-image, and draw another horizontal line between point b and its scope-image
  2. fill the trapezoid whose sides are two horizontal lines drawn in the previous step, the line connecting a and b, and the line connecting the images of a and b.

enter image description here

    \documentclass[border=2pt]{standalone}
    \usepackage{tikz}

    \usetikzlibrary{matrix,positioning,calc}
    \usetikzlibrary{decorations.pathmorphing,arrows.meta}
    \tikzset{>={Latex[width=2mm,length=2mm]}}

    \usepackage{environ}
    \NewEnviron{xmirror}[2]{
    \BODY
    \begin{scope}[xscale= #1,xshift=#2]\BODY\end{scope}
    }


    \begin{document}
    \begin{tikzpicture}

    \begin{xmirror}{-1}{-4cm}
    \draw [fill=yellow] (0,0) -- ++(0.4,0) coordinate(a) node[right]{a} -- ++(1,-2) coordinate(b) node[right]{b} -- ++(0,-0.2) -- ++(-0.2,0) -- ++(0,-0.2) -- ++(-0.2,0) -- ++(0,0.4) -- cycle ;
    \end{xmirror}

    \end{tikzpicture}
    \end{document}
Diaa
  • 9,599
  • 1
    from example I suspect, that the nodes in mirrored shape are in wrong position (this can not be handled by used approach). lines between a and b already exist or should be between this two point be double line? – Zarko Apr 03 '17 at 12:21
  • @Zarko I am sorry, I didn't get your question. – Diaa Apr 03 '17 at 12:36
  • please, explain (again) what is the problem in image you shopw in question: position of nodes at mirrored shape? filling area between this two shapes? drawing double lines between a and b? or something else ? – Zarko Apr 03 '17 at 12:41
  • @Zarko please take a look at my updated question. – Diaa Apr 03 '17 at 12:42
  • see, if i correctly understood your question :) – Zarko Apr 03 '17 at 12:51
  • The answer looks great, I will get back to it in minutes. – Diaa Apr 03 '17 at 12:52

3 Answers3

5

like this:

enter image description here

or this:

enter image description here

differences are in labels. in second case in the code below are deleted:

\documentclass[tikz, border=2pt]{standalone}
\usetikzlibrary{arrows.meta, backgrounds, calc, 
                decorations.pathmorphing,
                matrix, positioning,}
\tikzset{>={Latex[width=2mm,length=2mm]}  
         }

\begin{document}
\begin{tikzpicture}
\draw [fill=yellow] (0,0) -- ++(0.4, 0) coordinate[label=0:a] (a1) 
                          -- ++(1.0,-2) coordinate[label=0:b] (b1) 
                          -- ++(0,-0.2) -- ++(-0.2,0) -- ++(0,-0.2)
                          -- ++(-0.2,0) -- ++(0,0.4) -- cycle;
\begin{scope}[xscale=-1, xshift=-4cm]
\draw [fill=yellow] (0,0) -- ++(0.4, 0) coordinate[label=180:a] (a2) 
                          -- ++(1.0,-2) coordinate[label=180:b] (b2)   
                          -- ++(0,-0.2) -- ++(-0.2,0) -- ++(0,-0.2) 
                          -- ++(-0.2,0) -- ++(0,0.4) -- cycle;
\end{scope}
\draw (a1) -- (a2)  (b1) -- (b2);
\scoped[on background layer]
\fill[cyan!10]   (a1) -- (b1) -- (b2) -- (a2) -- cycle;
\end{tikzpicture}
\end{document}

Unfortunately with your approach this is possible only if you by hand determine coordinates a1 ... b2. To my opinion is simpler to copoy shape and than scale and shift as is done above.

Zarko
  • 296,517
5

Here is an amalgamation of the original approach and Zarko's answer. The main point is to use a macro

\somepart[options for scope environment]{name}

that draws the yellow part once and labels the relevant positions by name-a and name-b.

\documentclass[border=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{backgrounds}
\newcommand\somepart[2][]%
  {\begin{scope}[#1]
   \draw[fill=yellow]
     (0,0)
     -- ++(0.4,0) coordinate(#2-a)
     -- ++(1,-2) coordinate(#2-b)
     -- ++(0,-0.2)
     -- ++(-0.2,0)
     -- ++(0,-0.2)
     -- ++(-0.2,0)
     -- ++(0,0.4)
     -- cycle ;
   \end{scope}%
  }
\begin{document}
\begin{tikzpicture}
  \somepart{left}
  \somepart[xscale=-1,xshift=-4cm]{right}
  \draw (left-a) -- (right-a)  (left-b) -- (right-b);
  \scoped[on background layer]
  \fill[cyan!10] (left-a) -- (left-b) -- (right-b) -- (right-a) -- cycle;
\end{tikzpicture}
\end{document}

enter image description here

gernot
  • 49,614
  • Thanks for this beautiful answer, but I need to understand something, why does latex automatically assign the argument in curly braces of \somepart{left} to coordinate(#2-a) and coordinate(#2-b)? is it because #2 inside coordinate is a mandatory input and arguments inside curly braces are always understood to be mandatory? – Diaa Apr 03 '17 at 13:24
  • 1
    If a command definition starts with \newcommand\mymacro[3]{...}, then it has three mandatory arguments named #1 to #3. If the command definition starts with \newcommand\mymacro[3][yippie]{...}, then the first argument (#1) is optional and #2 and #3 are mandatory. If no optional argument is provided, than yippie is used as value of #1. Here, \somepart is defined as \newcommand\somepart[2][]{...}, which means that the first argument is optional (default value is empty) and the second one is mandatory. So \somepart{left} is the same as \somepart[]{left}. – gernot Apr 03 '17 at 13:30
  • Many thanks for considering my question. So, regarding your example of three arguments, if I defined it as \newcommand\mymacro[3][ ][ ]{...}, it would have #1 and #2 as optional arguments, while #3 is mandatory, am I right? – Diaa Apr 03 '17 at 13:40
  • 1
    No, this only works with one optional argument. If you want to have more flexibility, like two optional arguments, use \DeclareDocumentCommand from the xparse package. See Different command definitions with and without optional argument. To handle your example, you have to write \usepackage{xparse}\DeclareDocumentCommand\mymacro{oom}. – gernot Apr 03 '17 at 13:43
  • Ohh I see, I appreciate your consideration, and I will take a look at this link. Have a nice day. – Diaa Apr 03 '17 at 13:46
2

TikZ defines its own kind of macros and call them pics. With pics, gernot's code can be simplified to:

\documentclass[border=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{backgrounds}
\tikzset{
    somepart/.pic={
        \draw[fill=yellow]
            (0,0)
            -- ++(0.4,0) coordinate(-a)
            -- ++(1,-2) coordinate(-b)
            |- ++(-0.2,-0.2)
            |- ++(-0.2,-0.2)
            -- ++(0,0.4)
            -- cycle ;
    }
}

\begin{document}
\begin{tikzpicture}
  \pic (left) at (0,0) {somepart};
  \pic[xscale=-1] (right) at (4,0) {somepart};
  \draw[fill=cyan!10] (left-a) -- (right-a) -- (right-b) -- (left-b)--cycle;
\end{tikzpicture}
\end{document}

Coordinate names defined inside the pic, like -a and -b can be referenced outside the pic with a prefix formed by the pic name: left-a or right-b.

enter image description here

Ignasi
  • 136,588
  • Many thanks for this simple and clean answer. Out of curiosity, is there a way to label a & b and their images as done in the first output of Zarko's answer? – Diaa Apr 04 '17 at 07:56
  • 1
    @DiaaAbidou Add the label inside pic code: coordinate[label=a](-a), coordinate[label=b](-b). In this case, as b labels are behind the filled part, if you want to see them, place the last command on a background layer: \begin{scope}[on background layer] \draw[fill=cyan!10] (left-a) -- (right-a) -- (right-b) -- (left-b)--cycle; \end{scope}. – Ignasi Apr 04 '17 at 09:06