pstricks and calc

Denis Girou Denis.Girou at idris.fr
Thu Aug 6 20:23:10 CEST 1998


-----------------------------------------------------------------------------
This is the PSTricks mailing list, devoted to discussions about computational
graphics in (La)TeX using the PSTricks package from Timothy van Zandt.
For help using this mailing list, see instructions at the end of message.
-----------------------------------------------------------------------------

>>>>> "Werenfried.Spit" == Werenfried Spit <w.spit at witbo.nl> writes:

    Werenfried.Spit> Wouldn't it be nice if the functionality of calc and pstricks
    Werenfried.Spit> were integrated. So one could do stuff like
    Werenfried.Spit> \def\leftshift{-1}
    Werenfried.Spit> \def\rightshift{1}
    Werenfried.Spit> \rput(1+\leftshift,0){left}
    Werenfried.Spit> \rput(1+\rightshift,0}{right}
    Werenfried.Spit> \rput(1+\leftshift,1){once more}
    Werenfried.Spit> \rput(1+\rightshift,1){and again}

    Werenfried.Spit> Alas, I tried but it didn't work. Not even wrapped up a little bit 
    Werenfried.Spit> in a macro:

    Werenfried.Spit> \usepackage{pstricks,calc}
    Werenfried.Spit> \newcounter{tmpc}
    Werenfried.Spit> \def\num#1{\setcounter{tmpc}{#1}\thetmpc}
    Werenfried.Spit> \num{1+1}
    Werenfried.Spit> \begin{pspicture}(5,5)
    Werenfried.Spit> \rput(1,1){1}
    Werenfried.Spit> \rput(1,\num{1+1}){1+1}
    Werenfried.Spit> \end{pspicture}

    Werenfried.Spit> leading to
    Werenfried.Spit> ! Undefined control sequence.
    Werenfried.Spit> \calc at pre@scan ...calc at open \else \let \calc at next 

  It doesn't work because PSTricks doesn't use the way expected by `calc'
(anyway, PSTricks was written before `calc'...)

  PSTricks doesn't use \setlength, as `calc' require, because it implement
a more powerful mechanism than (La)TeX and allow to use dimensions without
explicit units, which is to say relative to the current unit, in the direction
(x, y, r) considered. It is why you can always said (3cm,2.5cm) but better
(3,2.5) which allow to have graphic objects with a definition independent of
the values of the units, which can scaled automatically.

  To do that, PSTricks never use the LaTeX \setlength and \addtolength macros,
but his own ones: \pssetlength, \pssetxlength, \pssetylength and
\psaddtolength. So, this is these ones that must be modified to interface them 
with `calc'.

  Remarks:

    * I have not tested these macros outside the following example.
So, it can heavily have pitfalls and break some other macros (the changed
macros are low level ones called very often and in various situations...)!
I have ever not tested the new versions of \pssetlength and \psaddtolength
which are not used in the example (but it is nearly the same code)!

    * Using counters, as `calc' also allow, is not very convenient as (La)TeX
counters must be integers. Using them for coordinates is obviously too
restrictive. So, we must use "lengths". The only obligation is that all
values must be suffixed by "pt", to say to TeX that these quantities are
dimensions.

    * `calc' is a pleasant piece of code which improve various macro packages
in a transparent way (it is his main strength). Nevertheless it is rather
limited. Some other packages (`realcalc' and `fp') exist and are a lot more
powerful. Comparing to `calc', their weakness is that they must be used in
two instructions, one to make the computation and to store the result in a
variable, and one other to use it. Nevertheless you can do more with them:
CTAN/macros/generic/realcalc
CTAN/macros/latex/contrib/other/fp

    * Your line: \def\num#1{\setcounter{tmpc}{#1}\thetmpc} was uncorrect.
Defining a LaTeX counter FOO with \newcounter create an internal (TeX)
counter named \c at FOO. So you must have wrote \the\c at tmpc

    * Using \the\c at tmpc would had the effect to insert the value of the
counter on the current page, which was obviously not at all your intention.
TeX macros are not Lisp functions which return the last value computed.
In fact you must store the value of the counter in a variable (a macro)
for later reuse.


\documentclass{article}

\usepackage{pstricks,calc}

\makeatletter

% Interface between `calc' and PSTricks.
% We redefine the \pssetlength, \pssetxlength, \pssetylength and
% \psaddtolength macros to use \setlength if we detect that the coordinate
% is a formula.

% Not heavily tested, take care!

% D.G. - August 6, 1998

\def\pssetlength#1#2{\pssetlength at i#1#2\@nil#2\@nil}
\def\pssetlength at i#1#2#3\@nil#4\@nil{%
\edef\@tempa{#3}%
\ifx\@tempa\@empty
  \edef\@tempa{#2}%         "Normal" way
\else
  \setlength\pst at dima{#4}% Formula detected: let `calc' do his job...
  \pst at dimtonum\pst at dima{\@tempa}%
\fi
\let\@psunit\psunit
\afterassignment\pstunit at off
#1 \@tempa\@psunit}

\def\psaddtolength#1#2{\psaddtolength at i#1#2\@nil#2\@nil}
\def\psaddtolength at i#1#2#3\@nil#4\@nil{%
\edef\@tempa{#3}%
\ifx\@tempa\@empty
  \edef\@tempa{#2}%         "Normal" way
\else
  \setlength\pst at dima{#4}% Formula detected: let `calc' do his job...
  \pst at dimtonum\pst at dima{\@tempa}%
\fi
\let\@psunit\psunit
\afterassignment\pstunit at off
\advance#1 \@tempa\@psunit}

\def\pssetxlength#1#2{\pssetxlength at i#1#2\@nil#2\@nil}
\def\pssetxlength at i#1#2#3\@nil#4\@nil{%
\edef\@tempa{#3}%
\ifx\@tempa\@empty
  \edef\@tempa{#2}%         "Normal" way
\else
  \setlength\pst at dima{#4}% Formula detected: let `calc' do his job...
  \pst at dimtonum\pst at dima{\@tempa}%
\fi
\let\@psunit\psxunit
\afterassignment\pstunit at off
#1 \@tempa\@psunit}

\def\pssetylength#1#2{\pssetylength at i#1#2\@nil#2\@nil}
\def\pssetylength at i#1#2#3\@nil#4\@nil{%
\edef\@tempa{#3}%
\ifx\@tempa\@empty
  \edef\@tempa{#2}%         "Normal" way
\else
  \setlength\pst at dima{#4}% Formula detected: let `calc' do his job...
  \pst at dimtonum\pst at dima{\@tempa}%
\fi
\let\@psunit\psyunit
\afterassignment\pstunit at off
#1 \@tempa\@psunit}

\makeatother

\pagestyle{empty}

\newcommand{\leftshift}{-1pt}
\newcommand{\rightshift}{1pt}

\psset{subgriddiv=0}

\Huge

\begin{document}

\begin{pspicture}(5,5)\psgrid
  \rput(1pt+\leftshift,0){left}
  \rput(1pt+\rightshift,0){right}
  \rput(1pt+\leftshift,1){once more}
  \rput(1pt+\rightshift,1){and again}
  %
  \rput(1,1pt + 1pt){\pscirclebox{A}} % (1,2)
  % (3.44,4.56)
  \rput(2.1pt + 4.3pt / \real{3.2},1.2pt + 1.6pt * \real{2.1}){\pscirclebox{B}}
\end{pspicture}

\end{document}

D.G.

-----------------------------------------------------------------------------
The list interface (subscription, information, access to the archives) is on:
http://www.tug.org/cgi-bin/lwgate/pstricks
Otherway to unsubscribe, send mail to pstricks-request at mail.tug.org
with a blank subject and in body the line unsubscribe <email-address>
-----------------------------------------------------------------------------



More information about the PSTricks mailing list