29

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?

28

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}

enter image description here

  • 6
    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
  • 1
    @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
  • 1
    @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
  • 1
    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
18

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).

enter image description here

17

enter image description here

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}
  • 1
    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
6

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}}}}}}
5

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

Result example 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}

Result 2

Result example 2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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