5

foreach how to fix the code below so that the center of the figure is at the origin (0,0)?

\begin{tikzpicture}
\fill[blue] circle (2pt) node[right] {$(0,0)$};
\draw (-3,1) -- (3,1);
\draw[blue] (-3,-2) -- (3,4);
\foreach \x in {1,2,3}{
    \foreach \y in {1,...,\x}{
        \draw[|-|] (\x,\y) -- ++(0,1);
    };
};
\foreach \x in {1,2,3}{
    \foreach \y in {1,...,\x}{
        \draw[|-|] (-\x,-\y+1) -- ++(0,1);
    };
};
\end{tikzpicture}

enter image description here

how to minimize the code? I minimize the code? See:

\begin{tikzpicture}
\fill[blue] circle (2pt) node[below right] {$(0,0)$};
\begin{scope}[yshift=-1cm]
\draw (-3,1) -- (3,1);
\draw[blue] (-3,-2) -- (3,4);

\foreach \x in {1,2,3}{
    \foreach \y in {1,...,\x}{
        \draw[|-|] (\x,\y) -- ++(0,1);
        \draw[|-|] (-\x,-\y+1) -- ++(0,1);
    };
};
\end{scope}
\end{tikzpicture}
Regis Santos
  • 14,463

3 Answers3

6

Assuming you don't want to change the individual coordinates, you can put the code within a scope and shift everything down 1cm as follows:

\documentclass{article}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\fill[blue] circle (2pt) node[right] {$(0,0)$};
\begin{scope}[yshift=-1cm]% Everything within here is shifted down 1cm
\draw (-3,1) -- (3,1);
\draw[blue] (-3,-2) -- (3,4);
\foreach \x in {1,2,3}{
    \foreach \y in {1,...,\x}{
        \draw[|-|] (\x,\y) -- ++(0,1);
    };
};
\foreach \x in {1,2,3}{
    \foreach \y in {1,...,\x}{
        \draw[|-|] (-\x,-\y+1) -- ++(0,1);
    };
};
\end{scope}
\end{tikzpicture}
\end{document}

Otherwise you can adjust the y-coordinate of each point is 1 unit less.

Peter Grill
  • 223,288
6

The accepted solution shifted the all those lines in the loops. Instead, I suggest to shift only the point which is labeled (0,0) as the origin. So, just change your origin code line to

\draw[fill=blue] (0,1) circle (2pt) node[below right] {$(0,0)$};

and you will get, with the rest of your code:

shifted origin

Stefan Kottwitz
  • 231,401
4

Fixes:

  • The |-| arrows have one disadvantages: The | part isn’t centered at the end of the line but touches it (as all arrows do). In a simple example like

    \draw[|-|] (0,0) -- (1,0);
    \draw[|-|] (1,0) -- (2,0);
    

    this becomes very obvious (line width set to 2pt):

    enter image description here

    This could be solved with the shorten > and shorten < keys set to -.5\pgflinewidth

  • … but I want to draw the vertical lines in one draw using the decorations.markings library. I can set the start position 1cm+.5\pgflinewidth and the end to 1. The step is set to 1cm.

    The .5\pgflinewidth is there for the same reason why I would have used the shorten keys in the previous fix. (The \arrows macro uses the same placement algorithms as the usual end-of-line arrows as can be seen in my answers to TikZ-pgf directed graph: change arrow color and location and Adding double arrows to the middle of a line with TikZ)

    Unfortunately, I can not set the end to 1+.5\pgflinewidth or <length of line>+.5\pgflinewidth. This would represent a marking that is not even on the line itself.

  • This is the reason I use the -| arrow after all, but with shorten >=-.5\pgflinewidth, so that the middle of the | lies directly on the line end.

  • The start of the line does not get a | arrow (with or without shortening) because we already have a horizontal line there.

  • The new macro \maxLineLength holds (half of) the number of lines, the unit-less length of the longest lines.

  • The whole picture has its center at (0,0) (the blue dot) and can be shifted and transformed in its entirety.

Code

\documentclass[tikz,border=5pt]{standalone}
\usetikzlibrary{decorations.markings}
\tikzset{
    |-|-|/.style={
        decoration={
            markings,
            mark=between positions {1cm+.5\pgflinewidth} and 1 step 1cm with {\arrow{|}},
        },
        postaction=decorate,
        -|,
        shorten >=-.5\pgflinewidth,
    },
}
\newcommand*{\maxLineLength}{3}
\begin{document}
\begin{tikzpicture}
\draw (-\maxLineLength,0) -- (\maxLineLength,0);
\draw[blue] (-\maxLineLength,-\maxLineLength) -- (\maxLineLength,\maxLineLength);

\foreach \x in {1,...,\maxLineLength}{
    \foreach \sign in {+,-}
        \draw[|-|-|] (\sign\x,0) -- ++(0,\sign\x);
};
\fill[blue] circle (2pt) node[below right] {$(0,0)$};% uses (0,0)
\end{tikzpicture}
\end{document}

Output (\maxLineLength = 3)

enter image description here

Output (\maxLineLength = 10)

enter image description here

Qrrbrbirlbel
  • 119,821