12

I want to draw a thick border for a shape (let's say a square) inside it and not on its center, like shown in the image. I am interested in obtaining the second case. Border drawn in the middle vs. border drawn inside

Unfortunately I cannot find any information regarding this. I would really appreciate if someone could help me with this. Thank you in advance.

The shape is drawn with the \filldraw command

\filldraw[fill=white, draw=yellow, line width=3mm] (0, 0) rectangle +(2, 2);
3
  • Hi Iam. Is it a node shape or arbitrary closed path that you consider ?
    – percusse
    May 15, 2015 at 15:05
  • It's a closed path. I've added the code.
    – Iam
    May 15, 2015 at 15:11
  • Related: Polygon drawn with an offset May 15, 2015 at 18:26

4 Answers 4

9

you can clip the half of it and then force it to draw it again double the line width. The scope limits the clipping effect.

\documentclass[tikz,border=5mm]{standalone}
\begin{document}
\begin{tikzpicture}
\begin{scope}
\clip[postaction={fill=white, draw=yellow, line width=6mm}] (0,0) rectangle +(2,2);
\end{scope}
\draw (0,0) rectangle (2,2);
\end{tikzpicture}
\end{document}

enter image description here

or using Mark Wibrow's further shortcut makes it a one-liner

\documentclass[tikz,border=5mm]{standalone}
\begin{document}
\begin{tikzpicture}
\draw[preaction={clip,postaction={fill=white, draw=yellow, line width=6mm}}]
     (0,0) rectangle +(2,2);
\end{tikzpicture}
\end{document}
3
  • 2
    You can actually add a postaction to a preaction so that everything can be done in one command without the scope environment: \draw [preaction={clip, postaction={draw=yellow, line width=6mm}}] (0,0) rectangle (2,2); May 15, 2015 at 16:05
  • @MarkWibrow Ah of course. Thanks, will update.
    – percusse
    May 15, 2015 at 16:13
  • 1
    Great solution. If you want to remove the black border, add draw=none before preaction.
    – Tom
    Apr 7, 2022 at 9:36
6

A poor man solution: if you know line width, you can adjust corners for an external rectangle

\documentclass[tikz,border=2mm]{standalone}

\begin{document}

\begin{tikzpicture}

\filldraw[fill=white, draw=yellow, line width=3mm] (0, 0) rectangle +(2, 2);
\draw[red] (0,0) rectangle +(2,2);
\draw[green] ([shift={(-1.5mm,-1.5mm)}]0,0) rectangle +([shift={(3mm,3mm)}]2,2);
\end{tikzpicture}
\end{document}

enter image description here

And if it's a node, draw a rectangle with corners in node's corners

\begin{tikzpicture}
\node[fill=white, draw=yellow, line width=3mm, minimum size=2cm] (a) {};
\draw[red] (a.south west) rectangle (a.north east);
\end{tikzpicture}

enter image description here

3

Done with MetaPost, for whom it interests. The drawinside macro takes a path p and a numeric wd as argument, fills p with the desired color for the drawing (here yellow) and unfills p, but shrinked by an amount wd. The blownup macro used for that comes from the Metafun format of MetaPost.

I have applied it on a square of length 3 cm and with a border of width 6 bp (bp = PostScript point). Of course, it can be any other (closed) path and any other width specified by the user.

\documentclass[border=2mm]{standalone}
\usepackage{luamplib}
  \mplibsetformat{metafun}
\begin{document}
  \begin{mplibcode}
    def drawinside (expr p, wd) =
      fill p withcolor yellow; unfill p blownup -wd;
    enddef;
    path sqr; sqr = fullsquare scaled 6cm;
    beginfig(1); 
      drawinside (sqr, 6bp); draw sqr dashed evenly withcolor red;
    endfig;
  \end{mplibcode}
\end{document}

To be typeset with LuaLaTeX. Output:

enter image description here

2

Assuming the use of nodes combined with the minimum width, minimum height and minimum size options to generate squares and/or rectangles, another possible solution would be to adjust the provided sizes by subtracting from them \pgflinewidth (there are two drawn lines in each direction and only half of each drawn line is drawn outside the shape, giving us 2*\pgflinewidth/2 = \pgflinewidth).

This means that we can draw a square/rectangle of any size that accounts for the size of the border such that the produced shapes have the right sizes. In the sample output below, the two shapes with the yellow border are drawn with no size adjustment. The same two shapes are drawn with a red border on top of them, but these shapes have their sizes adjusted by subtracting from them \pgflinewidth. The opacity of the adjusted shapes is reduced to showcase the effect.

Output:

Output

Solution:

\documentclass[tikz,border=2mm]{standalone}

\tikzset{%
  regularsquare/.style={line width=2pt,draw=yellow,fill=white,minimum size=1cm},
  adjustedsquare/.style={line width=2pt,draw=yellow,fill=white,minimum size=1cm-\pgflinewidth},
  regularrectangle/.style={line width=4pt,draw=yellow,fill=white,minimum height=0.5cm,minimum width=1cm},
  adjustedrectangle/.style={line width=4pt,draw=yellow,fill=white,minimum height=0.5cm-\pgflinewidth,minimum width=1cm-\pgflinewidth},
}

\begin{document}
\begin{tikzpicture}

  \node[regularsquare,] at (0,0) {};
  \node[adjustedsquare,draw=red,opacity=0.5,] at (0,0) {};
  \node[regularrectangle,] at (0,-1.2cm) {};
  \node[adjustedrectangle,draw=red,opacity=0.5,] at (0,-1.2cm) {};

\end{tikzpicture}
\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .