Obviously this only defines anchors for center, north, north east, and south west, but it can be fairly easily extended to provide south, east, west, north west and south east (as demonstrated in my answer).

Caveat:

As pointed out by Andrew Stacey in his answer, there was a slight discrepancy between the positioning of these pseudo-anchor coordinates and the anchors on a normal rectangular node. The edge-based solution above originally placed the pseudo-anchors exactly on the coordinates of the rectangle whereas on a rectangular node they would be placed at the outside edge of the lines of the rectangle. Although this was only likely to cause issues with thick line widths I have now added some x/yshifting to the above code to compensate.

The following image shows the difference in anchor positioning between standard node rectangles, the original edge-based solution (without x/yshifting) and the above (revised) edge-based solution (with x/yshifting). The line widths for the lower pictures are set to 0.5cm.

Node rectangle labelling code to illustrate the key to the colours (and for the generally curious):

@Andrew (/other experienced users): Would it make sense to put the method I was using as an answer instead of including it in the question? (I ask as I've just gained the privilege to do so, without waiting 8 hours or so.)
– StavesMar 12 '12 at 10:27

1

No. The right place for your code was in the question as the question was "Here's what I'd like to do, here's what I've tried, is there a better way?" so the code is a definite "plus" to the question as it shows you've put some effort in already. Anyone reading this will see your code and can use it if they wish so moving it to an answer doesn't actually help anyone.
– Loop SpaceMar 12 '12 at 19:01

@Staves edge [draw opacity=0] is not pretty and you can insert after (3,2) coordinate (path_rectangle center)
– Alain MatthesMar 12 '12 at 23:50

@Altermundus: I think you must have meant after rectangle you can insert the center coordinate - but that's neat, I'll add it in to the question code, cheers. With regards to the edge [draw opacity=0] bit, would you consider edge [draw=none] prettier? (Now that I know about [draw=none], from Andrew's answer, I'm going to add it in anyway as it seems somewhat cleaner to me.)
– StavesMar 13 '12 at 11:41

6 Answers
6

I think that the best way to establish node-like anchors is to use a node. I'm guessing that the annoyance of using an actual node to draw the rectangle is that specifying a node rectangle by its coordinates is a little more complicated than just saying (0,0) rectangle (3,2). So here's some code that puts an invisible (rectangular - but that's only because the default is a rectangle) node around the current path. If the path is more complicated then the node is guaranteed to contain the rectangular bounding box.

The green line is to show that the bounding box used is that of the path and not the current picture. The thick lines are to show that the node anchors are on the proper border of the path, not the "theoretical" path[1].

Here's the result:

[1]: With your method of specifying anchors via coordinates, the anchors would be on the "theoretical" path, namely the north west anchor would be at (3,2) not (3 + half line width, 2 + half line width). If you prefer this, it's easy to modify this method to do that.

Edit Now copes with scale=2 as Altermundus asked about. With more complicated transformations then it gets increasingly difficult to keep track since nodes work differently, and it is working on the actual bounding box rather than the path itself. So in those cases, caveat texer.

That's great - thank you very much ^^ You're quite correct that the reason I'm not using a node is that it cannot be simply defined by corner coordinates, as the path can. Also I'm glad you pointed out the "theoretical" path versus proper border aspect. I hadn't noticed the difference as the lines I'm using are predominately thin. Are the draw=none and fill=none lines in the tikzset necessary? (They don't seem to affect the output for me - perhaps a better question is: could you give a case using this where they would come into play?)
– StavesMar 12 '12 at 9:13

@Staves: It's protection against an every node/.style={draw} type command earlier in the path or scope or picture. There are probably other settings that should also be reset, but those were the most obvious ones. The point (such as there was one) was to ensure that the node was truly invisible.
– Loop SpaceMar 12 '12 at 9:17

That's a nice solution, I agree that it's cleaner than the edge-based one I presented :)
– StavesMar 13 '12 at 17:03

1

Wow, this is great. One question: Why the use of coordinate in \draw (1,0) coordinate rectangle (4,3) [add reference=R1] ;. I have always used that without coordinate and your example seems to work fine without it. So, just wondering if there is some hidden benefit to including coordinate? Or, are there other commands with similar syntax that require the use of coordinate?
– Peter GrillMar 14 '12 at 16:08

Nice, thank you for this it also helped me to understand @Andrew's answer better. As a side-note, I'm not sure if it's worth drawing the rectangle with an initial \draw command, as opposed to relying on the \node command to draw it and simply defining a and b beforehand as follows: \coordinate at (0,0) (a); \coordinate at (3,2) (b); \node [draw=red,fit=(a) (b),inner sep=0] (box) {};
– StavesMar 12 '12 at 9:22

@Staves No, it's not worth. I just wanted to show you that fitting rectangle with inner sep=0 had exactly the same size of the original one. As you can see in the example, the red rectangle covers the blue one.
– IgnasiMar 12 '12 at 9:56

Or rather I couldn't see! ;) But thanks, I understand what you mean :)
– StavesMar 13 '12 at 15:50

With further experimentation I've realised the coordinates don't even need to be defined before the \node command, so the whole rectangle can be created with: \node [fit={(0,0) (3,2)},inner sep=0pt] (box) {}; Just in case anyone else didn't know that besides me :)
– StavesMar 13 '12 at 17:14

I've proposed an edit to this answer with an additional, and slightly more minimal, example given which is the basis for the code I'll actually be using. (Hopefully Ignasi will approve/adapt it as I'd rather that happen than posting my own minor variation of this answer.)
– StavesMar 13 '12 at 18:08

I add another answer because in my first answer I did not want to use the notion of node. I think it's not in the spirit of TikZ to impose these kinds of conditions to a node but if you want a simple code to this::