%% $Id: xyrotate.doc,v 3.3 1996/12/18 09:40:16 ross Exp $ %% %% Xy-pic ``Rotate and Scale extension'' option. %% Copyright (c) 1993-1996 Ross Moore %% %% This file is part of the Xy-pic package for graphs and diagrams in TeX. %% See the companion README and INSTALL files for further information. %% Copyright (c) 1991-1996 Kristoffer H. Rose %% %% The Xy-pic package is free software; you can redistribute it and/or modify %% it under the terms of the GNU General Public License as published by the %% Free Software Foundation; either version 2 of the License, or (at your %% option) any later version. %% %% The Xy-pic package is distributed in the hope that it will be useful, but %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY %% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License %% for more details. %% %% You should have received a copy of the GNU General Public License along %% with this package; if not, write to the Free Software Foundation, Inc., %% 675 Mass Ave, Cambridge, MA 02139, USA. %% \ifx\xyloaded\undefined \input xy \fi \xyprovide{rotate}{Rotate and Scale extension}{\stripRCS$Revision: 3.3 $}% {Ross Moore}{ross@mpce.mq.edu.au}% {Mathematics Department, Macquarie University, NSW~2109, Australia} \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% This extension provides the ability to request that any object be displayed rotated at any angle as well as scaled in various ways. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \paragraph*{Header:}\leavevmode \DOCHEADER \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% These are effects which are not normally available within \TeX. Instead they require a suitable `back-end' option to provide the necessary |\special| commands, or extra fonts, together with appropriate commands to implement the effects. Thus $$ \xy *+\txt<.8\hsize>{Using this extension will have no effect on the output unless used with a backend that explicitly supports it.} *\frm{-} \endxy $$ \DOCMODE( \xydef@\xyundefinedRotate@#1#2@@{%\egroup % \xywarning@{The #1 #2 effect is not implemented with the current driver.}}% \DOCMODE) The extension provides special effects that can be used with any \Xy-pic by defining |[||]| modifiers. The modification is local to the currently being built, so will have no effect if this object is never actually used. The following table lists the modifiers that have so far been defined. They come in two types -- either a single keyword, or a key-character with the following text treated as a single argument. % \begin{defs} |[@]| & align with current direction\cr |[@||]| & align to \cr |[@!||]| & rotate degrees\cr % |[@=||]| & make |[||]| repeat the current transformations\cr % |[@*]| & use previous transformations \cr \noalign{\smallskip} |[*||]| & scale by \cr |[*|$_x$,$_y$|]| & scale $x$ and $y$ separately \cr %\noalign{\smallskip} % |[<||]| & shear y-axis to \cr \noalign{\smallskip} |[left]| & rotate anticlockwise by 90$^\circ$ \cr |[right]| & rotate (clockwise) by 90$^\circ$ \cr |[flip]| & rotate by 180$^\circ$; same as |[*-1,-1]| \cr |[dblsize]| & scale to double size \cr |[halfsize]| & scale to half size \cr \end{defs} % These |[||]| modifiers specify transformations of the currently being built. If the object has a rectangle edge then the size of the rectangle is transformed to enclose the transformed object; with a circle edge the radius is altered appropriately. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \TODO: There should be an |[@*]| form which repeats the set of transformations applied to the last object which has been transformed, possibly in an earlier diagram. Also an |[@=||]| form allowing a set of transformations to be saved and used later, simply by specifying |[||]|. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \medskip Each successive transformation acts upon the result of all previous. One consequence of this is that the order of the shape modifiers can make a significant difference in appearance---in general, transformations do not commute. Even successive rotations can give different sized rectangles if taken in the reverse order. Sometimes this change of size is not desirable. The following commands are provided to modify this behaviour. % \begin{defs} |\NoResizing| & prevents size adjustment \cr |\UseResizing| & restores size adjustments \cr \end{defs} % \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \DOCMODE( \xydef@\NoResizing{\xyNoResizing@} \xydef@\UseResizing{\xyUseResizing@} \xydef@\xyNoResizing@{% \global\let\origxyrescale@=\xyrescale@ \global\let\origxyrotSizeMod@=\xyrotateSizeMod@ \global\let\xyNoResizing@=\xyNoResizing@@ \global\let\xyUseResizing@=\xyUseResizing@@ \xyNoResizing@@ } \xydef@\xyNoResizing@@{% \global\let\xyrescale@=\xyignorescale@ \global\let\xyrotateSizeMod@=\xyignoreSizeMod@ } \xylet@\xyUseResizing@=\relax \xydef@\xyUseResizing@@{% \global\let\xyrescale@=\origxyrescale@ \global\let\xyrotateSizeMod@=\origxyrotSizeMod@ } \DOCMODE) \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \noindent The |\NoResizing| command is also useful to have at the beginning of a document being typeset using a driver that cannot support scaling effects, in particular when applied to whole diagrams. In any case an unscaled version will result, but now the spacing and positioning will be appropriate to the unscaled rather than the scaled size. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \paragraph*{Interface} Recognize the characters and keywords. \DOCMODE( \xydefcsname@{shape [@...]}#1{\xyrotatechar@#1@@}% \xydefcsname@{shape [<...]}#1{\xyshearchar@{#1}@@}% \xydefcsname@{shape [*...]}#1{\xyscalechar@{#1}@@}% \xydefcsname@{shape [left]}{\xyshape@left@} \xydefcsname@{shape [right]}{\xyshape@right@} \xydefcsname@{shape [flip]}{\xyshape@flip@} \xydefcsname@{shape [halfsize]}{\xyshape@halfsize@} \xydefcsname@{shape [dblsize]}{\xyshape@dblsize@} \xydefcsname@{shape [vflip]}{\xyshape@vflip@} \xydefcsname@{shape [hflip]}{\xyshape@hflip@} \DOCMODE) \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Each style modifier adds code to one, or both, of two global lists. These contents of these lists, called |\preXYtransform@@| and |\postXYtransform@@|. An implementation must define macros which are to be bound to the control sequence names |\preXYtransform@| and |\postXYtransform@|, which are prepended and appended to the |\Drop@@| and |Connect@@| methods for the current . Also |\Drop@@| and |\Connect@@| must be modified, if this has not already been done as indicated by |\xy@transform@| having expansion |\relax|. \DOCMODE( \xydef@\preXYtransform@{} \xydef@\postXYtransform@{} \xywarnifdefined\preXYtransform@@ \xywarnifdefined\postXYtransform@@ \gdef\preXYtransform@@{} \gdef\postXYtransform@@{} \xydef@\xy@transform@{} \xydef@\preShape@@{} \xydef@\postShape@@{} \DOCMODE) The transformations must be implemented by emulating the adjoint coordinate transformations. This requires that code be added to |preXYtransform@@| in reverse order to the order of occurrence of the modifiers. The code is added to |\postXYtransform@@| in natural order, so that each addition to |\preXYtransform@@| can be closed off, if necessary, in a correctly nested sequence. \DOCMODE( \xydef@\modXYtransform@{% \ifx\xy@transform@\empty \transformDrop@\transformConnect@\resetTransform@\fi %\show\preShape@@ \DN@##1{\expandafter\def\expandafter\tmp@\expandafter{##1}}% \expandafter\next@\expandafter{\preShape@@}% \DN@##1{\expandafter\gdef\expandafter\preXYtransform@@\expandafter{% \tmp@ ##1}}\expandafter\next@\expandafter{\preXYtransform@@}% \DN@##1{\expandafter\def\expandafter\tmp@\expandafter{##1}}% \expandafter\next@\expandafter{\postShape@@}% \DN@##1{\expandafter\gdef\expandafter\postXYtransform@@\expandafter{% \postXYtransform@@ ##1}}\expandafter\next@\expandafter{\tmp@}}% \xydef@\transformDrop@{\let\xy@transform@=\relax \expandafter\def\expandafter\Drop@@\expandafter{% \expandafter\preXYtransform@\Drop@@\postXYtransform@}} \xydef@\transformConnect@{\let\xy@transform@=\relax \expandafter\def\expandafter\Connect@@\expandafter{% \expandafter\preXYtransform@\Connect@@\postXYtransform@}} \xydef@\resetTransform@{\gdef\preXYtransform@@{}\gdef\postXYtransform@@{}} \DOCMODE) \BUG: The reference point does not move correctly in \PS\ when a shift modifier has been applied before a rotation. The object prints outside of its bounding |\rectangleEdge|. Fix this!! Global macros are used, so that the same styles can be reused by successive objects without having to re-interpret modifiers, as described next. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \paragraph*{Saving transformations} Once specified for an , the collection of transformations can be assigned a name, via |[>||]|. The here is any collection of letters or other characters up to the closing |]|. Subsequent use of |[>||]|, with the same or other s, will re-establish the saved transformations, acting on the new with initial reference point appropriate to this . \NOTE: Such namings are global and permanent. They are intended to allow a particular set of transformations to be easily repeated for different objects inside various pictures and diagrams within the same document. \DOCMODE( \xydef@\xynametransform@#1{% \DN@{\expandafter\gdef\expandafter#1\expandafter{\the\toks@}}\next@ } \DOCMODE) \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \paragraph*{Scaling and Scaled Text} The modifier can contain either a single scale factor, or a pair indicating different factors in the $x$- and $y$-directions. Negative values are allowed, to obtain reflections in the coordinate axes, but not zero. \DOCMODE( \xydef@\xyscalechar@#1@@{\xyscalechars@#1,#1,@@} \xydef@\xyscalechars@#1,#2,#3@@{% \DN@{\xyrescale@(#1,#2)}% \dimen@=#1\p@ \ifdim\dimen@>\z@ \else \ifdim\dimen@<\z@ \else \DN@{\xywarning@{invalid scaling factors #1, #2}}% \fi\fi \dimen@=#2\p@ \ifdim\dimen@>\z@ \else \ifdim\dimen@<\z@ \else \DN@{\xywarning@{invalid scaling factors #1, #2 }}% \fi\fi \next@ } \xydef@\xyrescale@(#1,#2){% \setboxz@h{\xyscale@@{#1}{#2}% \dimen@=\ifx-#1\R@c\advance\dimen@-\R@c \dimen@=-\dimen@ \else#1\L@c \advance\dimen@-\L@c\fi \kern\dimen@\boxz@\kern-\dimen@}% \R@c=\if-#1\L@c\else#1\R@c\fi \L@c=\if-#1\R@c\else#1\L@c\fi \U@c=\if-#2\D@c\else#2\U@c\fi \D@c=\if-#2\U@c\else#2\D@c\fi } \xydef@\xyignorescale@(#1,#2){\xywarning@{Ignoring rescale: #1,#2}% \setboxz@h{\xyscale@@{#1}{#2}\boxz@}}% \DOCMODE) \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Some particular scalings. \DOCMODE( \xydef@\xyshape@halfsize@{\xyrescale@(.5,.5)} \xydef@\xyshape@dblsize@{\xyrescale@(2,2)} \xydef@\xyshape@flip@{\xyrescale@(-1,-1)} \xydef@\xyshape@vflip@{\xyrescale@(1,-1)} \xydef@\xyshape@hflip@{\xyrescale@(-1,1)} \DOCMODE) \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \paragraph*{Rotation and Rotated Text} Within |[@...]| the |...| are parsed as a locally, based on the current direction. The value of count register |\Direction| contains the information to determine the requested direction. When no is parsed then |[@]| requests a rotation to align with the current direction. The special sequence |[@!...]| is provided to pass an angle directly to the back-end. The \Xy-pic size and shape of the with |\rectangleEdge| is unchanged, even though the printed form may appear rotated. This is a feature that must be implemented specially by the back-end. For example, using the \PS\ back-end, |[@!45]| will show the object rotated by 45$^\circ$ inside a box of the size of the unrotated object. \DOCMODE( \xydef@\xyrotatechar@{\bgroup \afterDIRECTIONorEMPTY{\xyrotateSizeMod@}{\xyFN@\xySpecialRotate@i}} \xydef@\xySpecialRotate@i{% \ifx \space@\next \expandafter\DN@\space{\xyFN@\xySpecialRotate@i}% \else\ifx @\next \let\next@=\xyrotateSizeMod@ \else\addEQ@\ifx \next \addEQ@\DN@##1@@{%\transformDrop@ \expandafter\xynametransform@\csname shape [##1]\endcsname\egroup}% \else\ifx !\next \DN@!{\egroup\getSpecialRotate@}% \else\ifx *\next \DN@*@@{\egroup\transformDrop@}% \else \DN@{\xySpecialRotate@@}% \fi\fi\fi\fi\fi \next@ } \xydef@\getSpecialRotate@{\doSpecialRotate@@} \DOCMODE) \TODO: Provide example of repeated, named transformation. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \paragraph*{Installation} Initially there is no support for the actual effects. They will be processed according to size/shape requirements, but the actual rotation or re-sizing is ommitted. A file is required to implement the effects. It need to define alternative expansions to which |\xyRotate@@#1|, |\xySpecialRotate@@#1@@|, |\doSpecialRotate@@#1@@| and |\xyscale@@#1#2| can be bound. \DOCMODE( \xydef@\xyRotate@#1{\xyundefinedRotate@{rotate}{#1}@@} \xydef@\xySpecialRotate@#1@@{\xyundefinedRotate@{rotate}{#1}@@\egroup} \xydef@\doSpecialRotate@#1@@{\xyundefinedRotate@{special rotate}{#1}@@} \xydef@\xyscale@#1#2{\xyundefinedRotate@{scale}{#1,#2}@@} \xydef@\UnloadRotate@#1{% \ifx#1\relax\else\xyunload@{rotation extension}\fi \let\xyRotate@@=\xyRotate@ \let\xySpecialRotate@@=\xySpecialRotate@ \let\doSpecialRotate@@=\doSpecialRotate@ \let\xyscale@@=\xyscale@ } \UnloadRotate@\relax \xyaddunsupport{rotate}{\UnloadRotate@\relax} \DOCMODE) \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% This adjusts the sizes of |\L@c|, |\R@c|, |\U@c| and |\D@c| appropriately. \DOCMODE( \xydef@\xyrotateSizeMod@ @@{% \L@p=\L@c \R@p=\R@c \U@p=\U@c \D@p=\D@c \ifdim\cosDirection\p@>\z@ \R@c=\cosDirection\R@p \L@c=\cosDirection\L@p \U@c=\cosDirection\U@p \D@c=\cosDirection\D@p \else \R@c=\cosDirection\L@p \L@c=\cosDirection\R@p \U@c=\cosDirection\D@p \D@c=\cosDirection\U@p \fi \advance\L@c \if-\sinDirection\D@p\else\sinDirection\U@p\fi \advance\R@c \if-\sinDirection\U@p\else\sinDirection\D@p\fi \advance\U@c \if-\sinDirection\L@p\else\sinDirection\R@p\fi \advance\D@c \if-\sinDirection\R@p\else\sinDirection\L@p\fi \dimen@ii=\L@c \advance\dimen@ii-\L@p \edef\tmp@{\egroup \L@c=\the\L@c \R@c=\the\R@c \U@c=\the\U@c \D@c=\the\D@c \dimen@ii=\the\dimen@ii \noexpand\setboxz@h\bgroup \noexpand\xyRotate@@{\the\Direction}}\tmp@ \xydropRotated@ } \xydef@\xydropRotated@@{% \kern\dimen@ii \boxz@ \kern-\dimen@ii \modXYtransform@ \egroup } \xylet@\xydropRotated@=\xydropRotated@@ \xydef@\xyignoreSizeMod@ @@{\xywarning@{Ignoring rotation}} \DOCMODE) Some particular rotations. \DOCMODE( \xydef@\xyshape@left@{\xyrotatechar@ v(0,1)@@} \xydef@\xyshape@right@{\xyrotatechar@ v(0,-1)@@} \DOCMODE) \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \paragraph*{Reflections} Reflections can be specified by a combination of rotation and a flip --- either |[hflip]| or |[vflip]|. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \paragraph*{Shear transformations} \DOCMODE( \xydef@\xyshearchar@{\xyundefinedRotate@{shearing}} \DOCMODE) \TODO: Provide the structure to support these; then implement it in \PS. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% The following diagram requires various options to be loaded and installed. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \xyrequire{rotate}\xyrequire{color}\xyrequire{crayon}\xyrequire{line}% \xyuncatcodes \paragraph*{Example} The diagram in figure~??[rotate and flips] illustrates many of the effects described above as well as some additional ones defined by the |color| and |rotate| extensions. \begin{figure*}[t] \begin{code} \UseCrayolaColors \xy\drop[*1.25]\xybox{\POS (0,0)*{A};(100,40)*{B}**{} ?<<*[@_][red][o]=<5pt>{\heartsuit}; ?>>>*[@_][Plum][o]=<3pt>{\clubsuit} **[|*][|.5pt][thicker]\dir{-}, ?(.1)*[left]!RD\txt{label 1}*[red]\frm{.} ?(.2)*[!gsave newpath xyXpos xyYpos moveto 50 dup rlineto 20 setlinewidth 0 0 1 setrgbcolor stroke grestore][psxy]{.}, ?(.2)*[@]\txt{label 2}*[red]\frm{.}, ?(.2)*[BurntOrange]{*}, ?(.3)*[halfsize]\txt{label 3}*[red]\frm{.} ?(.375)*[flip]\txt{label 4}*[red]\frm{.} ?(.5)*[dblsize]\txt{label 5}*[red]\frm{.} ?(.5)*[WildStrawberry]{*}, ?(.7)*[hflip]\txt{label 6}*[red]\frm{.} ?(.8)*[vflip]\txt{label 7}*[red]\frm{.} ?(.9)*[right]!LD\txt{label 8}*[red]\frm{.} ?(.5)*[@][*.66667]!/^30pt/ \txt{special effect: aligned text} *[red]\frm{.} }\endxy \end{code} $$\docode$$ \caption{Rotations, scalings and flips} ??=[rotate and flips] \end{figure*} \begin{exercise} Suggest the code used by the author to typeset ??[rotate and flips]. \answercode \answertext{This is how the author specified the diagram:} \answertext\displaycode \end{exercise} The actual code is given in the solution to the exercise. Use it as a test of the capabilities of your DVI-driver. The labels should fit snugly inside the accompanying rectangles, rotated and flipped appropriately. \BUG: This figure also uses colours, alters line-thickness and includes some \PS\ drawing. The colours may print as shades of gray, with the line from $A$ to $B$ being thicker than normal. The wider band sloping downwards may have different width and length according to the DVI-driver used; this depends on the coordinate system used by the driver, when `raw' \PS\ code is included. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \paragraph*{The end \& Log}\leavevmode \DOCMODE( \xyendinput % $Log: xyrotate.doc,v $ % Revision 3.3 1996/12/18 09:40:16 ross % no changes % % Revision 3.2 1995/09/19 18:21:41 ross % Bug fix release. % % Revision 3.1 1995/09/05 20:36:33 ross % Release! % % Revision 3.0 1995/07/07 20:13:19 ross % Major release w/new User's Guide! % % Revision 2.13 1995/07/04 15:04:51 ross % Ready for release of v3. % % Revision 2.12 1994/10/25 03:01:14 ross % Final 3beta release [bug fixes & AMS-LaTeX fitting]. % % Revision 2.11 1994/07/05 06:38:37 ross % some documentation was left out previously % % Revision 2.10 1994/06/15 12:46:03 ross % Second release 3beta. % Colour and line style saving works; label colouring bug fixed. % % Revision 2.9 1994/06/09 14:39:49 ross % Release 3beta. % % NEW file to go in version 2.9 by Ross Moore. \DOCMODE) \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Tell Emacs that this is a LaTeX document and how it is formatted: % Local Variables: % mode:latex % fill-column:77 % fill-prefix:"" % End: