Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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}

enter image description here

share|improve this question
    
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
add comment

2 Answers

up vote 42 down vote accepted

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{adjustbox}[2011/11/14]
\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:
\newcommand{\somespecialrotate}[2][]{\adjustbox{#1,angle={#2},lap=-.5\width+.5\Width}}

\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}}%
    \advance\@tempdima by -.5\wd\@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}

Result

Lower part:

Result2

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

share|improve this answer
    
Brilliant! Thank you. –  Dan Nov 17 '11 at 10:55
20  
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
add comment

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}

enter image description here

share|improve this answer
    
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
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.