# How to rotate a box in-place

The following LaTeX code illustrates my question. Is it possible to get what I want without doing the negative \hskip, as I want a simple generic solution which will rotate the box to any angle (center origin) but leave it 'in-place'?

An ideal solution would allow me to do this:

{a}\somespecialrotate[origin=c]{\anyangle}{b}


\documentclass{article}
\usepackage{graphicx}
\usepackage{xcolor}
\begin{document}
\newsavebox\bxa
\newsavebox\bxb
\huge
\savebox\bxa{\color{red}\rule{1cm}{1cm}}
\savebox\bxb{\color{black}\rule{1cm}{1cm}}
\usebox\bxa\rotatebox[origin=c]{45}{\usebox\bxb}This is what I do not want\par
\usebox\bxa\hskip-0.25cm\rotatebox[origin=c]{45}{\usebox\bxb}This is what I DO want
\end{document}


-
The behaviour here is deliberate (and actually takes work at the low level). Do you want a 'higher-level' package solution or one that uses only graphicx? –  Joseph Wright Nov 17 '11 at 10:53
If it can be done simply with the graphicx package, that would be good. –  Dan Nov 17 '11 at 10:58
@Dan: I added now an alternative solution which only uses graphicx. –  Martin Scharrer Nov 17 '11 at 12:05

This can be easily done with adjustbox v0.8 from 2011/11/14. It provides the original width as \Width which can be used to center the rotated content around it (with the rest overlapping on the left and right) or to calculate the amount which the rotated content should overlap to the left, which is the \hskip you are talking about. The current width is always \width, so lap=-.5\width+.5\Width will make the rotated content lap over to the left. See the adjustbox manual for details.

With an older version of adjustbox you can substitute \Width with \wd\bxb if you box the content by yourself. If you don't want to use adjustbox, but rather do it yourself, you need to box both the original content (\bxb) and the rotated one (say \bxc) and then use \mbox{\hskip\dimexpr -.5\wd\bxb+.5\wd\bxc\relax\usebox\bxc} to typeset the box.

\documentclass{article}
\usepackage{xcolor}
\begin{document}
\newsavebox\bxa
\newsavebox\bxb
\huge
\savebox\bxa{\color{red}\rule{1cm}{1cm}}
\savebox\bxb{\color{black}\rule{1cm}{1cm}}
\usebox\bxa\rotatebox[origin=c]{45}{\usebox\bxb}This is what I do not want\par
\usebox\bxa\hskip-0.25cm\rotatebox[origin=c]{45}{\usebox\bxb}This is what I DO want

\usebox\bxa\adjustbox{origin=c,angle=45,center=\Width}{\usebox\bxb}This is with the original width

\usebox\bxa\adjustbox{origin=c,angle=45,lap=-.5\width+.5\Width}{\usebox\bxb}This is with overlapping only at the left

% As macro:

\usebox\bxa\somespecialrotate[origin=c]{15}{\usebox\bxb}This is some text\par
\usebox\bxa\somespecialrotate[origin=c]{25}{\usebox\bxb}This is some text\par
\usebox\bxa\somespecialrotate[origin=c]{35}{\usebox\bxb}This is some text\par
\usebox\bxa\somespecialrotate[origin=c]{45}{\usebox\bxb}This is some text\par
\usebox\bxa\somespecialrotate[origin=c]{55}{\usebox\bxb}This is some text\par
\usebox\bxa\somespecialrotate[origin=c]{65}{\usebox\bxb}This is some text\par
\usebox\bxa\somespecialrotate[origin=c]{75}{\usebox\bxb}This is some text\par
\usebox\bxa\somespecialrotate[origin=c]{85}{\usebox\bxb}This is some text\par
\usebox\bxa\somespecialrotate[origin=c]{95}{\usebox\bxb}This is some text\par
\end{document}


Here a graphicx-only solution which only uses one temporary box register:

\documentclass{article}
\usepackage{graphicx}
\usepackage{xcolor}

\makeatletter
\newcommand{\somespecialrotate}[3][]{%
\begingroup
\sbox\@tempboxa{#3}%
\@tempdima=.5\wd\@tempboxa
\sbox\@tempboxa{\rotatebox[#1]{#2}{\usebox\@tempboxa}}%
\mbox{\hskip\@tempdima\usebox\@tempboxa}%
\endgroup
}
\makeatother

\begin{document}
\huge
{\color{red}\rule{1cm}{1cm}}\somespecialrotate[origin=c]{45}{\color{black}\rule{1cm}{1cm}}This is some text\par
{\color{red}\rule{1cm}{1cm}}\somespecialrotate[origin=c]{30}{\color{black}\rule{1cm}{1cm}}This is some text\par

\end{document}


Lower part:

And here for angles from 0,5,...,180:

-
Brilliant! Thank you. –  Dan Nov 17 '11 at 10:55
Show off! Great! :D –  qubyte Nov 17 '11 at 11:54
Reminds me of when they decided to put some Bach on the CD they sent out on Voyager - I think it was Carl Sagan who said it would be showing off! <:-) Bach was a compatriot of Martin's, ich denke. –  Brent.Longborough Nov 17 '11 at 14:35
little mistake in \mbox{\hskip\dimexpr -.5\wd\bxb+.5\bxbc\relax\usebox\bxc} ?? \bxc instead of \bxbc ?. but I'm not sure I try this method in my question tex.stackexchange.com/questions/46073/… but with no success –  Alain Matthes Feb 28 '12 at 18:24

use \makebox to get the same width without rotating:

\documentclass{article}
\usepackage{graphicx}
\usepackage{xcolor}
\newsavebox\bxa
\newsavebox\bxb
\makeatletter
\newcommand\somespecialrotate[3][]{%
\sbox\bxa{#3}\makebox[\wd\bxa]{\rotatebox[#1]{#2}{#3}}}
\makeatother
\def\RotateBox#1#2{\sbox{\bxa}{#2}\sbox\bxb{\rotatebox[origin=c]{#1}{#2}}%
\makebox[\wd\bxa]{\usebox\bxb}\kern\dimexpr(\wd\bxb-\wd\bxa)/2\relax}
\begin{document}
\huge
\color{red}\rule{1cm}{1cm}%
\rotatebox[origin=c]{45}{\color{black}\rule{1cm}{1cm}}This is what I do not want\par
\rule{1cm}{1cm}%
\RotateBox{45}{\color{black}\rule{1cm}{1cm}}This is what I DO want\par

\color{red}\rule{1cm}{1cm}%
\somespecialrotate[origin=c]{45}{\color{black}\rule{1cm}{1cm}}

\end{document}


-
The problem with that is the OP apparently wants the right side to keep is new size, so that the text is not printed on top of the rotated square. Here the 'T' of 'This' overlaps with it. –  Martin Scharrer Nov 17 '11 at 11:12
If I was not worried about the overlap on the right how could I create a macro which used this \makebox idea so I could do: {a}\somespecialrotate[origin=c]{\anyangle}{b} I can't see why my attempt below does NOT work: –  Dan Nov 17 '11 at 14:55
\makeatletter\newcommand{\somespecialrotate}[3][]{\sbox\@tempboxa{#3}\makebox[\‌​wd\@tempboxa]{\rotatebox[#1]{#2}{#3}}}\makeatother –  Dan Nov 17 '11 at 14:56
@Dan: see my edited answer, it has your macro. –  Herbert Nov 17 '11 at 15:10
Thank you. Is it my use of @tempboxa which causes it to fail? –  Dan Nov 18 '11 at 16:26