# Shear transform a “box”

Using the graphicx package, I can make any arbitrary box rotated using the \rotatebox{...}{...} command. Is there a comparable command in any package that lets me shear a box, i.e., producing a kind of general slanting?

With a slightly more recent pdfTeX than in David's answer, you can more directly do affine transforms using \pdfsetmatrix. I don't claim to know anything about this, but here is roughly what graphicx does under the hood in \rotatebox (with a different matrix, of course).

\documentclass{article}
\newsavebox{\foobox}
\newcommand{\slantbox}[2][.5]
{%
\mbox
{%
\sbox{\foobox}{#2}%
\hskip\wd\foobox
\pdfsave
\pdfsetmatrix{1 0 #1 1}%
\llap{\usebox{\foobox}}%
\pdfrestore
}%
}
\begin{document}
\slantbox{Hello, world!}

\slantbox[-2]{Hello, world!}
\slantbox[-1]{Hello, world!}
\slantbox[-.8]{Hello, world!}
\slantbox[-.6]{Hello, world!}
\slantbox[-.4]{Hello, world!}
\slantbox[-.2]{Hello, world!}

\slantbox[.2]{Hello, world!}
\slantbox[.4]{Hello, world!}
\slantbox[.6]{Hello, world!}
\slantbox[.8]{Hello, world!}
\slantbox[1]{Hello, world!}
\slantbox[2]{Hello, world!}

\end{document}


• Do we want this for LaTeX3? It should be pretty easy to code as I've already got the basics sorted. – Joseph Wright Jul 13 '12 at 17:10
• I'm still a bit confused. How do those four numbers correspond to a transformation matrix? Is it just a list of elements of the matrix left to right, row by row? Would \slantbox[0]{} amount to the identity transformation? – Seamus Jul 13 '12 at 17:15
• @Joseph: I was thinking of it (I didn't upvote your comment, so at least one other person would like that), but I'm not sure whether we should give \box_linear_transform:Nnnnn for arbitrary parameters, or \box_vertical_shear:Nn and \box_horizontal_shear:Nn, or... – Bruno Le Floch Jul 13 '12 at 17:59
• @BrunoLeFloch If we provide a mechanism here, we should have the 'general case' shear, something like \box_shear:Nnn or even as you say a totally-general transformation (\box_affine:Nnnnn?). One for LaTeX-L – Joseph Wright Jul 13 '12 at 18:40
• Indeed I was thinking of \pdfliteral. I've confused your answer with David's probably. But maybe it is possible to use directly that command in your case too. Great answer anyway and I hope it goes into the L3 magic. – percusse Jul 14 '12 at 17:48

Aha, TikZability opportunity!

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\begin{scope}[cm={1,0,1,1,(0,0)}] % Sets the coordinate trafo matrix entries.
\node[transform shape] at (0,0) {ABC};
\end{scope}
\begin{scope}[cm={1,0,-1,1,(0,0)}]
\node[transform shape] at (3,0) {Hello};
\end{scope}
\begin{scope}[cm={1,0,-1,-1,(0,0)}]
\node[transform shape] at (2,2) {World};
\end{scope}
\begin{scope}[cm={1,0,1,-1,(0,0)}]
\node[transform shape] at (1,2) {FOObar?};
\end{scope}
\end{tikzpicture}
\end{document}


You can put into nodes instead of boxes (with less risk :P).

• 'transform shape' is not needed – Black Mild Jun 2 at 15:23

You can mess with the coordinate matrix, but at your own risk...

\documentclass{article}

\begin{document}

ABC\pdfliteral{ q 2 0.1 0.6 .4 0 0 cm}\rlap{XYZ}\pdfliteral{ Q}

\end{document}

• q (\pdfsave) and Q (\pdfrestore) should be used at the same place. Otherwise the coordinate system of TeX and its output device get indeed messed up. – Heiko Oberdiek Jun 19 '14 at 15:36
• @HeikoOberdiek ah yes I wrote some driver graphics back end files once, clearly I forgot everything, I'll add an rlap.... – David Carlisle Jun 19 '14 at 15:49

Shear transforms can be decomposed into scalings and rotations.

% \hshearbox{vertical_prescale_times_shearfactor}{one_divide_by_shearfactor}{content}
% an initial vertical downscale is often necessary for a 3d projection
\newcommand{\hshearbox}[3]{\scalebox{0.866025}[#2]{\rotatebox{210}%
{\scalebox{1.73205}[-0.57735]{\rotatebox{60}{\scalebox{-1.1547}[#1]{#3}}}}}}
% \vshearbox{horizontal_prescale_times_shearfactor}{one_divide_by_shearfactor}{content}
% an initial horizontal downscale is often necessary for a 3d projection
\newcommand{\vshearbox}[3]{\scalebox{#2}[0.866025]{\rotatebox{210}%
{\scalebox{-0.57735}[1.73205]{\rotatebox{60}{\scalebox{#1}[-1.1547]{#3}}}}}}


A little late, but perhaps useful. An easier solution is the use of xslant and yslant in the node options.

## Example 1

\documentclass{standalone}
\usepackage{tikz}
\begin{tikzpicture}
\node[yslant=0.5, draw] (1) {Latex};
\node[xslant=0.5, draw, anchor=south] at ([yshift=10]1.north) {Latex};
\end{tikzpicture}


## Result 1

Then I wanted to use it for a 3D view of a box, where on one plane I project an external *.png image.

## Example 2

\documentclass[convert]{standalone}
\usepackage{tikz}

\newcommand{\w}{4 cm} % width of the box
\newcommand{\dep}{1 cm} % depth of the box
\newcommand{\h}{0.7 cm} % height of the box

\begin{document}
\begin{tikzpicture}
% Front side of the box
\node[minimum width = \w, minimum height=\h, fill=gray, outer sep =0] (front) {};
\begin{scope}
\pgftransformxslant{1}
\pgfset{minimum width=\w, minimum height= \dep, outer sep = 0}
\pgftransformshift{\pgfpointanchor{front}{north}}
\pgfnode{rectangle}{south}{}{clip}{\pgfusepath{clip}}
% Image on top of the box
\node[anchor=south, inner sep =0, xslant=1, outer sep = 0] (img) at (front.north)
{\includegraphics[width=\w, height=\dep]{Example_image.png}};
\end{scope}
% Side of the box
\node[anchor=west, yslant=1, minimum height =\h, minimum width=\dep,
inner sep=0, outer sep=0, fill=black!70] at (front.east) {};
\end{tikzpicture}
\end{document}