Notes
- I have removed the
calc library and used the keys xshift and yshift directly on the center node.
The ; in your defintion of \object is actually not needed as you group the last argument anyway. With your definition, even \object[](,)text; is possible. Without the ; you must write \object[](,){text} (though an additional ; wouldn’t hurt than either).
However, I have not changed your argument definition.
I have provided an improved version of your macro:
- I have replaced your
\definition with a \newcommand that allows the first parameter to be optional.
- The algorithm to create the rectangle is—with the help of another node—re-written.
The \pgfkeys in your macro sets the /object/angle key globally. Unless you make the change local (by including your macro in a set of braces { }) or backup its value it will not be changed.
The line
\def\@angle{0}
will only change the \@angle macro, not the key!
There are other ways to “get” one value of PGF key. One would be the use of \pgfkeysgetvalue or \pgfkeysvalueof:
\pgfkeysgetvalue{<key>}{<macro>} saves the value of <key> in <macro>:
\pgfkeys{/object/.cd,#1}
\pgfkeysgetvalue{/object/angle}\@angle
\pgfkeysvalueof{<key>} expands to the current value of <key>:
\pgfkeys{/object/.cd,#1} % and three lines later:
\draw [rotate around={\pgfkeysvalueof{/object/angle}:(center)}] ([xshift=-1cm,yshift=-.5cm]center) coordinate (#4 a) rectangle ++(2,1);
You could also save the value directly to a macro:
Handler /.store in or /.estore in (expand its argument before saving):
\pgfkeys{
/object/.cd,
angle/.store in=\@angle,
angle=0,
}
Then \@angle can be used without the need to extra “get” the value inside the macro.
The handler .store in is just a short-cut, internally \def\@angle{#1} is used. In fact, we can use .code to even calculate the argument. In this case, that does not make much sense because we use the angle only with rotate or rotate around. These keys are already usable with a calculation (e.g. rotate=360-25+2*10).
\pgfkeys{
/object/.cd,
angle/.code=\pgfmathsetmacro\@angle{#1},
angle=0,
}
Code
\documentclass[tikz]{standalone}
\makeatletter
\pgfkeys{
/object/.cd,
angle/.initial=0,
}
\def\object[#1](#2,#3)#4;{{
\pgfkeys{/object/.cd,#1,angle/.get=\@angle}
\node (center) at (#2,#3) {#4};
\coordinate (#4 center) at (center);
\draw [rotate around={\@angle:(center)}] ([xshift=-1cm,yshift=-.5cm]center) coordinate (#4 a) rectangle ++(2,1);
}}
\makeatother
\begin{document}
\begin{tikzpicture}
\object[](0,0){A};
\object[angle=30](3,0){B};
\object[](6,0){C};
\draw (A a) -- (B center);
\end{tikzpicture}
\end{document}
Output

Improvement (?)
Nodes do already understand the concept of rotation but not only is the shape rotated the content is too.
My solution provides two nodes that will be created:
- the un-rotated one with the text (in the example below in lightgray), name:
x-<name>; and
- the rotated rectangle with text hidden, name:
<name>.
Where <name> is either the name that is provided by the /object/name key or if that is empty the the node’s content (#4) is used.
The rotated node contains the text in \phantom so that it gets resized the same as the un-rotated node in case that the text is bigger than the minimum dimensions.
If you only want an \object to be rectangular, add shape=rectangle to the \node commands. Otherwise it could happen that a shape specification that is given to the command’s scope is used.
Code
\documentclass[tikz]{standalone}
\makeatletter
\pgfkeys{
/object/.cd,
angle/.initial=0,
name/.initial={},
}
\newcommand*{\object}[1][]{\@object[#1]}
\def\@object[#1](#2,#3)#4;{{
\pgfkeys{/object/.cd,#1}
\pgfkeysgetvalue{/object/name}\@name% saves /object/name in \@name
\ifx\@name\pgfutil@empty\edef\@name{#4}\fi% if no name is given use #4
\node[
draw=lightgray,% debug
minimum width=2cm, minimum height=1cm, name/.expand once=x-\@name] at (#2,#3) {#4};
\node[draw,minimum width=2cm, minimum height=1cm, name/.expand once=\@name, rotate=\pgfkeysvalueof{/object/angle}] at (#2,#3) {\phantom{#4}};
}}
\makeatother
\begin{document}
\begin{tikzpicture}
\object(0,0){A};
\object[angle=30](3,0){B};
\object[name=C has another name](6,0){C};
\draw (A.south west) -- (B.center);
\draw[red] (B.north east) -- (x-B.north west) -- (C has another name.mid west);
\draw[blue,bend right,->] (A) edge (B)
(B) edge (C has another name);
\end{tikzpicture}
\end{document}
Output

node.southfor example? This is exactly the reason why you must not use.in coordinate/node names. Because the.is used to distinguish between the coordinate/node name (here:node) and the anchor (here:south). – Qrrbrbirlbel Jan 25 '13 at 17:27centerorA center. It would just make your life more difficult. – percusse Jan 25 '13 at 21:53(A.input a)and(B.output). I'll go through your long answer tomorrow since it's late here. – Chris Jan 25 '13 at 22:15circuitslibraries (ch. 29, pp. 290ff.) or thecircuitikzpackage that served as the inspiration for the TikZ libraries? My guess: You won’t need to create your own shapes and anchors. On that note: Defining new (real) anchors needs either an already defined shape where you just add anchors or a new shape (that can be defined from scratch or inherits some of its defintion from other shapes). Either way: What’s your real use-case scenario? – Qrrbrbirlbel Jan 25 '13 at 23:10rectanglenode. If those do not help you, you are entitled to ask a follow-up question. – Qrrbrbirlbel Jan 26 '13 at 12:27#4 a) without the.. Of course there shouldn't be another node that is actually named in the same matter! Other than that, I can’t see any disadvantages. It is not a real anchor but close enough, I guess. – Qrrbrbirlbel Jan 26 '13 at 16:40