# tikz: Can we set the corner coordinates of a rectangle?

\tikzstyle{block} = [draw, fill=yellow!20, text centered, rectangle,
minimum height=0.8cm,minimum width=6em, align=right]


First, I can obtain a rectangle by

\node (rect) [block] at (0,0) {test};


Second, I can also obtain a rectangle by

\draw (0,0) rectangle (1,1);


Question: I want to use the first way to create a rectangle, whose properties have been predefined using \tikzstyle. If using the second way, I have to define the properties of the rectangle again. I know the coordinates of the corners of the rectangle can be obtained by

• rect.north east
• rect.north wast
• rect.south east
• rect.south west

Can I create a rectangle using the first way and specify the four corner coordinates of the rectangle?

-
You have conflicting objectives, you are providing a minimum width but then asking to be 1cm wide and high. Note that a node is not a ordinary path, it's a more complex object. –  percusse Dec 23 '12 at 1:31
–  Qrrbrbirlbel Dec 23 '12 at 2:00
@percusse The rectangle path could not care less about the node specific styles (only the unknowing user might wonder). More interestingly, I find text centered and align=right, though my current PGF manual does not know about text centered anyway. –  Qrrbrbirlbel Dec 23 '12 at 2:07
@Qrrbrbirlbel Yes you have even more for example text badly ragged; check line 775 onwards in tikz.code.tex file. They are kind of the older (or maybe lower) versions of align=.... options. I know them from the auto-complete options of QTikZ. –  percusse Dec 23 '12 at 2:13
@percusse I have only said that my manual doesn’t know about them. ;) After all, there were no error messages, so TikZ at least knew them. And yes, they practically are align= without setting the node halign header. On that note, @Shiyu: align=right overwrites text centered. –  Qrrbrbirlbel Dec 23 '12 at 2:35

Yes, you can.

Though, I limited your question to two corner coordinates, because unless you account for rotation, two coordinates suffice to specify a rectangle.

## So many possibilities.

But before I divulge the actual solution to you let me give you some other ideas on positioning.

1. The anchor= key. It can be used as for example anchor=south west (see my example below) which set the south-west corner of the to-placed node at the at part.
2. With the positioning library you can even be more specific and could specify above right=<distance> of <coordinate> where <coordinate> can be an actual coordinate like 0,0 (enbrace the whole argument in { } when you use , in it!), a node or a node’s anchor.

Unless <distance> is specified, none is used. This topic is a bit complex, it is best to read subsection 16.5.3 “Advanced Placement Options” of the PGF manual.

3. The fit library and its fit= key. The fit key takes a list of coordinates (or nodes, or anchors) and fits the to-be-fitted node so that those coordinates are enclosed by that node. But be aware of the inner sep key and the usual dimension-setting keys (height, width, etc.) as they can affect the placement; usually the corners do not lie at those coordinates.

4. My solution: the from=<coordinate 1> to <coordinate2> key. See the last point on the next list.

## So many styles.

I have created four distinctive styles:

1. block filldraw contains
• draw and
• fill options. It is used in the other styles and on the rectangle path.
2. block rect contains
• block filldraw (and inherits its option) and
• the node-specific rectangle option (which is the default). This style can be applied to an path but doesn’t change much for the path unless it contains a node which would than inherit those node-specific styles (but not the draw and fill styles).
3. block contains
• block rect,
• minimum height and
• minimum width. Again, it does not change much for paths but for nodes.
4. from style (that should be used on a node) takes its argument in the form

from=<coordinate 1> to <coordinate 2>


Now, those coordinates can be just arbitrary 0,0 but than the whole argument must be enclosed in { } (as I did in my example below). But they also can be nodes and their anchors. <coordinate 1> will be used as the lower left corner in the above right=of key.

Both coordinates will be used to calculate the horizontal and vertical dimensions for the node. Note that I have used the minimum width and minimum height keys to set the needed dimensions. In this case, the node will grow with its content.

In the example I have set the opacity key to see the overlaying nodes and how they get positioned.

## Code

\documentclass[tikz,border=2pt]{standalone}
\usetikzlibrary{positioning}
\tikzset{
block filldraw/.style={% only the fill and draw styles
draw,
fill=yellow!20,
},
block rect/.style={% fill, draw + rectangle (without measurements)
block filldraw,
rectangle,
},
block/.style={% fill, draw, rectangle + minimum measurements
block rect,
minimum height=0.8cm,
minimum width=6em,
},
from/.style args={#1 to #2}{
above right={0cm of #1},% needs positioning library
to={#1}{#2},
minimum width=\xdiff,
minimum height=\ydiff,
},
to/.code 2 args={%
\gettikzxy{\xfirst}{\yfirst}{#1}%
\gettikzxy{\xsecond}{\ysecond}{#2}%
\pgfmathsetmacro\xdiff{\xsecond-\xfirst}%
\pgfmathsetmacro\ydiff{\ysecond-\yfirst}%
}
}
\makeatletter
\newcommand*{\gettikzxy}[3]{%
\tikz@scan@one@point\pgfutil@firstofone(#3)\relax
\edef#1{\the\pgf@x}%
\edef#2{\the\pgf@y}%
}
\makeatother
\begin{document}
\begin{tikzpicture}[opacity=.4]
\draw[block filldraw]              (0,0) rectangle (1,1)       ;
\node[block] (rect)             at (0,0)                 {test};
\node[block, anchor=south west] at (0,0)                 {test};
\node[block rect, from={0,0 to 2,.5}]                 {from-to};

\foreach \x/\y/\pos in {0/0/below,1/1/above,2/.5/right}{
\fill[opacity=1] (\x,\y) circle (1pt) node [\pos] {$\x,\y$};
}
\end{tikzpicture}
\end{document}


## Code with fit and animation

\documentclass[tikz,border=2pt]{standalone}
\usetikzlibrary{positioning,fit}
\tikzset{
block filldraw/.style={% only the fill and draw styles
draw,
fill=yellow!20,
},
block rect/.style={% fill, draw + rectangle (without measurements)
block filldraw,
rectangle,
},
block/.style={% fill, draw, rectangle + minimum measurements
block rect,
minimum height=0.8cm,
minimum width=6em,
},
from/.style args={#1 to #2}{
above right={0cm of #1},
to={#1}{#2},
minimum width=\xdiff,
minimum height=\ydiff,
},
to/.code 2 args={%
\gettikzxy{\xfirst}{\yfirst}{#1}%
\gettikzxy{\xsecond}{\ysecond}{#2}%
\pgfmathsetmacro\xdiff{\xsecond-\xfirst}%
\pgfmathsetmacro\ydiff{\ysecond-\yfirst}%
}
}
\makeatletter
\newcommand*{\gettikzxy}[3]{%
\tikz@scan@one@point\pgfutil@firstofone(#3)\relax
\edef#1{\the\pgf@x}%
\edef#2{\the\pgf@y}%
}
\makeatother
\def\hideme#1{\ifnum\iCount<#1\relax\tikzset{every node/.style={opacity=0}}\fi}
\begin{document}
\foreach \iCount in {0,...,4}{
\begin{tikzpicture}[opacity=.6]
\draw[block filldraw]              (0,0) rectangle (1,1)       ;
\hideme1
\node[block] (rect)             at (0,0)                 {test};
\hideme2
\node[block, anchor=south west] at (0,0)                 {test};
\hideme3
\node[block rect, from={0,0 to 2,.5}]                 {from-to};
\hideme4
\node[block rect, fit={(0,0)(1,1)}]                       {fit};

\foreach \x/\y/\pos in {0/0/below,1/1/above,2/.5/right}{
\fill[opacity=1] (\x,\y) circle (1pt) node [opacity=1, \pos] {$\x,\y$};
}
\end{tikzpicture}
}
\end{document}


## Output with fit and animation

-
Nice. You can also get the same effect by \node[block,fit={(0,0)(1,1)}] {test}; with inner and outer sep dimensions reset to zero and minimum size removed (via fit library). –  percusse Dec 23 '12 at 3:08
@percusse Well, now that you have mentioned it, I’ll add fit to my answer. Though I find the need to set the seps to zero as a disadvantage. Nonetheless, it is a valid option and, in other cases, a good alternative. –  Qrrbrbirlbel Dec 23 '12 at 3:31
Dear Lord! So many solutions. Tikz is always much more complicated than I think. Thanks a lot! Excellent answer! –  Shiyu Dec 23 '12 at 4:25
+1 good answer (I added the animation). –  Paul Gaborit Dec 23 '12 at 8:21