[Xy-pic] Problem with skewing(?)

Ross Moore ross at ics.mq.edu.au
Sun Mar 28 03:41:22 CEST 2004


Hello Richard,

On 24/03/2004, at 9:58 PM, Richard Lewis wrote:

> Hi everyone,
>
> I am trying to define a command \SliceObj (that will take three
> arguments: top, label and bottom) to typeset a vertical arrow, framed  
> with parentheses (...),
> whose reference point should be the middle of the label.
>
> Something like
>
>    /       \
>   |  {#1}   |
>   |   |     |
>   |   |{#2} |
>   |   |     |
>   |   V     |
>   |  {#3}   |
>    \       /
>
> with the reference in the middle of {#2}
>
> I can draw the arrow and frame it (See attached .tex file), and I
> thought i could use the skewing operator (!) to move the reference
> point to the new positon:
>
> "arrow-with-frame"!<new position>
>
> However I can't get this to work: the position we end up after the
> skew is not <new position>, as (i think) the attached file shows, what
> am i doing wrong?

Provided that I understand correctly what you are trying to do,
I find 3 "errors" in your coding...

> \newcommand{\SliceObj}[3]{%
>   %%% vertical arrow: #1=source, #2=target, #3=LABEL
>   %% 1. c is where we start.  We draw an arrow starting 0.6cm above c,  
> and
>   %%    ending 0.6cm under c.
>   \POS+<0cm,0.6cm>*+{#1}="TOP"+<0cm,-1.2cm>*+{#3}="BASE"
>   \POS\ar"TOP";"BASE"^-{#2}="LABEL"
>   %% 2. join all 3 bits together, reference is at "LABEL"
>   \POS"LABEL"."TOP"."BASE"
>   %% 3. add brackets `(' and `)' around the joined thing
>   *\frm{(}*\frm{)}="joined-thing",
>   %% 4. Add margin, using !C to ensure we get equal space all around  
> the
>   %%    joined-thing
>   %%    [I am using *+\frm{.} so we can see where the object at
>   %%    "SOBJ-with-margin" extends to---when i get \SliceObj to work i
>   %%    will want to use *+\frm{}, to get a margin (but no frame)]
>   "joined-thing"!C*+\frm{.}="SOBJ-with-margin",
>   %% 5. now set the reference point
>   "SOBJ-with-margin"*{\circ},        %we are here before skew
>   "joined-thing"*{\oplus},           %want reference to be here
>   %% try and skew reference of SOBJ-with-margin to joined-thing
>   "SOBJ-with-margin"!"joined-thing"="here"*{\otimes},
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------- see below
>   "here"                             %here is where our reference ended
> }


Firstly:

   %% try and skew reference of SOBJ-with-margin to joined-thing
    "joined-thing"."SOBJ-with-margin"="here"*{\otimes},
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Doesn't this do what you want ?

The reference point of a merged object is at the coords
of the reference-point of the 1st <POS> in the merge.

The skew (!) operator is not the appropriate thing for
merging different <POS>s. It is for shifting the base-point
within a given <POS>.


Now the \otimes and \oplus should coincide for each of
your SOBJs.  --- call these the  (x+)-points.

>
> %\sobj gives a `stand alone' \SliceObj
> \newcommand{\sobj}[3]{\xygraph{[]!{\SliceObj{#1}{#2}{#3}}}}
>

Secondly:

While this \SliceObj is a valid command for adding to
an Xy-pic diagram, it does not create just a single <object>.

To make a single <object>, with your current approach,
you need a slight modification, using \xybox :

\newcommand{\SliceObj}[3]{\drop\xybox{%
   ....
   ....
    }%  end of \xybox
}%  end of \SliceObj


> \section{More complicated Diagrams}
> More complicated diagram: We \emph{should} get a `corner' and then $x$
> and $y$ on top of each other in the bottom-left position\ldots

This doesn't happen because the <POS> before your [d] hop
is further to the right than you want it to be, since
\SliceObj  has placed several <object>s, at different places.

Using \xybox, so that there is just one compound <object>
placed, you now get the 'x' and 'y' coinciding.


However, the place where they coincide may not be where
you want them to be...

... that is, the arrows between your SOBJs do not
emanate from the (x+)-points, and the 'xy' does
not align with the  (x-)-points.


Thirdly:

   the \xybox  does not allow control over *where*,
inside the <object> that it builds,
the reference point is to be located.

Accordingly, I've just devised a variant that builds
the same kind of compound <object>, but also sets
its reference-point to be at the <coord> of the
last <POS> within the box; i.e., the <coord> for
the <object> that has been built is at the current
<POS> when the Xy-pic parsing has been completed.
The LRUD extents are the size of the complete box;
i.e., *not* the extents of the final <POS>.

Here is coding that should go in your document's
preamble -- eventually it should be added to  xy.tex


---------  start of new Xy-pic definitions  -------

\makeatletter   % adjust the \catcode of @

\xydef@\xyobjbox#1{\xy#1\endxyobj\Edge at c={\rectangleEdge}\computeLeftUpn 
ess@}

\xydef@\endxyobj{\if\inxy@\else\xyerror@{Unexpected \string\endxy}{}\fi
  \relax
   \dimen@=\Y at max \advance\dimen at -\Y at min
   \ifdim\dimen@<\z@ \dimen@=\z@ \Y at min=\z@ \Y at max=\z@ \fi
   \dimen@=\X at max \advance\dimen at -\X at min
   \ifdim\dimen@<\z@ \dimen@=\z@ \X at min=\z@ \X at max=\z@ \fi
   \edef\tmp@{\egroup
     \setboxz at h{\kern-\the\X at min \boxz@}%
     \ht\z@=\the\Y at max \dp\z@=-\the\Y at min \wdz@=\the\dimen@
     \noexpand\maybeunraise@ \raise\dimen@\boxz@
     \noexpand\recoverXyStyle@ \egroup \noexpand\xy at end
     \U at c=\the\Y at max \advance\U at c-\the\Y at c
     \D at c=-\the\Y at min \advance\D at c\the\Y at c
     \L at c=-\the\X at min  \advance\L at c\the\X at c
     \R at c=\the\X at max  \advance\R at c-\the\X at c
    }\tmp@}

\makeatother   % revert \catcode of @

---------  end of new Xy-pic definitions  -------


Now, if your definition starts:

   \newcommand{\SliceObj}[3]{\drop\xyobjbox{%
                             ^^^^^^^^^^^^^^

then you should get the correct (?) alignments.



> %!Z{#1}{#2} sets scale to #1 by #2
> % [ Is there really no predefined version of this?? ]
> \newgraphescape{Z}[2]{!{0;<#1,0pc>:<0pc,#2>::0}}

Well, there are at least 4 possible parameters to be fully
general, allowing for skew (i.e. non-rectangular) bases.
It's simple enough to do yourself, so we didn't bother.

>
>  %!S{#1}{#2}{#3} gives a \SliceObj inside an \xygraph
> \newgraphescape{S}[3]{[]!{\SliceObj{#1}{#2}{#3}}}
>
> %%% This one gives an infinite loop
> %% \xygraph{!Z{3cm}{3cm}
> %%   !S{11111111}23 (?:[r] !S{1}{222222}{3},
> %%                   ?:[d] !S{1}{2}{333333})
> %% }

Hmm.
This is hard to trace.
I'm still working on it.


Hope this helps,

	Ross Moore



>
> %%% This one also runs forever
> %% \xygraph{!Z{3cm}{3cm}
> %%   !S{11111111}{2}{3}="start"
> %%   "start":[r] !S{1}{222222}{3}
> %%   "start":[d] !S{1}{2}{333333}
> %% }
>
> %%% This one compiles, but the reference points are all wrong
> \begin{equation}
> \xygraph{!Z{3cm}{3cm}
>   !S{11111111}{2}{3}="start" [r] !S{1}{222222}{3}="right"
>   "start"[d] !S{1}{2}{333333}="down"
>   "start":"right"
>   "start":"down"
>   %% here we show that the \otimes really is the reference point
>   "right"[d]{x}
>   "down"[r]{y}
> }
> \end{equation}
>
> \end{document}
>
> %%% Local Variables:
> %%% mode: latex
> %%% TeX-master: t
> %%% End:_______________________________________________
> xy-pic mailing list
> http://tug.org/mailman/listinfo/xy-pic
>
------------------------------------------------------------------------
Ross Moore                                         ross at maths.mq.edu.au
Mathematics Department                             office: E7A-419
Macquarie University                               tel: +61 +2 9850 8955
Sydney, Australia                                  fax: +61 +2 9850 8114
------------------------------------------------------------------------



More information about the xy-pic mailing list