Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I just want to draw a dot if the condition is satisfied and otherwise cancel the drawing of the single dot. The following code is the simplified version of my real scenario. Please don't suggest other methods because the part I want to learn is to abort drawing.

The code below is intended to draw a dot for each point on the x-axis whenever its abscissa is an even number. More precisely, there is no dot for odd abscissa.

\documentclass[pstricks,border=12pt,12pt]{standalone}
\usepackage{multido}
\SpecialCoor
\begin{document}
\begin{pspicture}[showgrid](-5,-5)(5,5)
    \multido{\i=-5+1}{11}{\qdisk(!\i\space 2 mod 0 eq {\i\space 0} {<don't draw a dot and continue the loop>} ifelse){2pt}}
\end{pspicture}
\end{document}

Is it possible to exit from the PostScript expression and abort the drawing just for certain dots that do not match the condition?

Edit

I want to get a solution that is useful not only for qdisk but also other graphic macros including the starred version.

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{multido}
\SpecialCoor

\begin{document}
% Herbert's method
\begin{pspicture}[showgrid](10,4)
    \multido{\i=1+1}{9}
    {
        \pscircle*(!\i\space dup 2 mod 0 ne {/SD {pop pop pop} def} if 1){5pt}
        \pscircle(!\i\space dup 2 mod 0 ne {/SD {pop pop pop} def} if 3){5pt}
    }
\end{pspicture}

% modified Herbert's method
\begin{pspicture}[showgrid](10,4)
    \multido{\i=1+1}{9}
    {
        \pscircle*(!\i\space dup 2 mod 0 ne {/SD {} def} if 1){5pt}
        \pscircle(!\i\space dup 2 mod 0 ne {/SD {} def} if 3){5pt}
    }
\end{pspicture}

% modified AlexG's method
\begin{pspicture}[showgrid](10,4)
    \multido{\i=1+1}{9}
    {
        \pscircle*(!\i\space dup 2 mod 0 ne {mark Rand Rand /SD {cleartomark} def} if 1){5pt}
        \pscircle(!\i\space dup 2 mod 0 ne {mark Rand Rand /SD {cleartomark} def} if 3){5pt}
    }
\end{pspicture}

% my attempt with other macros
\begin{pspicture}[showgrid](10,4)
    \multido{\i=1+1}{9}
    {
        % compilable but result in a wrong output
        \psframe
            (!\i\space dup 2 mod 0 ne {/SD {pop pop pop} def} if .2 sub 2.8)
            (!\i\space dup 2 mod 0 ne {/SD {pop pop pop} def} if .2 add 3.2)
        %--------------------------------------------------------------------------------
        % does not compile with  GhostScript
        %\psframe
            %(!\i\space dup 2 mod 0 ne {mark Rand Rand /SD {cleartomark} def} if .2 sub 2.8)
            %(!\i\space dup 2 mod 0 ne {mark Rand Rand /SD {cleartomark} def} if .2 add 3.2)
    }
\end{pspicture}
\end{document}

Outputs in the same order.

enter image description here

enter image description here

enter image description here

enter image description here

share|improve this question
    
So by "abort the drawing" do you mean you want to not draw the \qdisk, or not draw the entire drawing at all (and fail the process completely)? –  Werner Jan 23 at 5:43
    
@Werner: Just abort the single dot that does not match the condition. –  Oh my ghost Jan 23 at 6:52
    
I would imagine this is possible if you draw the disk directly in PS rather than using the interface provided by pstricks. That way you can condition on even/odd and draw something/not. –  Werner Jan 23 at 7:05

2 Answers 2

up vote 5 down vote accepted

No, this is not possible due to the stack nature of Postscript.

In this specific situation, the verbatim Postscript argument (!...) simply puts the disk coordinates on the operand stack. The disk itself gets drawn later, when the PS procedure SD (it implements the disk drawing) is put on the stack and executed.

In order to not draw selected disks, the code in the else-clause of your example would have to jump into a future state of the operand stack, that is, on top of the SD procedure. This is impossible, since SD hasn't arrived there yet.

All you can do is to temporarily redefine SD to clear the operand stack up to a certain position defined with the mark keyword:

\documentclass[pstricks,border=12pt,12pt]{standalone}
\usepackage{multido}
\SpecialCoor
\begin{document}
\begin{pspicture}[showgrid](-5,-5)(5,5)
  \multido{\i=-5+1}{11}{\qdisk(!
    \i\space 2 mod 0 eq {\i\space 0} % put desired disk coordinates on the stack if condition is fulfilled 
    { %else
      mark  % mark stack position up to which the operand stack needs to be cleared
      -1 -1 % put some dummy coords on the stack to satisfy operators that come in between them and SD
      /SD {cleartomark} def % redefine SD to clear the stack upto the previously defined position
    } ifelse){2pt}}
\end{pspicture}
\end{document}

UPDATE:

For any other PSTricks graphical command you will have to look into its implementation to figure out which bit requires modification. Here are the \pscircle and \psframe examples:

\documentclass[pstricks,border=12pt,12pt]{standalone}
\usepackage{multido}
\SpecialCoor

\begin{document}
  \begin{pspicture}[showgrid](10,4)
    \multido{\i=1+1}{9}
    {
      \pscircle*(!\i\space dup 2 mod 0 ne
        {
          mark  % mark stack position up to which the operand stack needs to be cleared
          exch  % swap \i and mark
          /arc {cleartomark} def % redefine arc to clear the stack upto the previously defined position
        } if 1
      ){5pt}
      \pscircle(!\i\space dup 2 mod 0 ne {mark exch /arc {cleartomark} def} if 3){5pt}
    }
  \end{pspicture}

  \begin{pspicture}[showgrid](10,4)
      \multido{\i=1+1}{9}
      {
          \psframe
          (!\i\space dup 2 mod 0 ne { mark exch /Frame {cleartomark} def } if .2 sub 2.8)
          (!\i\space .2 add 3.2)
          %procedure `Frame' executed around here.
      }
  \end{pspicture}
\end{document}
share|improve this answer
    
+1 Could you please explain what your code does such that I can reuse it as a template for my other projects in the future? –  Oh my ghost Jan 23 at 8:19
    
Do you have any idea about my other question here. –  Oh my ghost Jan 23 at 8:28
    
@CodeMocker: I edited a second time. The mark keyword is inserted only if the condition is false. –  AlexG Jan 23 at 8:52
    
@CodeMocker Ok. Herbert's answer is much shorter. He knows better how many operands to remove. Nevertheless, the essence is the same, SD needs to be redefined. –  AlexG Jan 23 at 9:21
    
See my updated question. Your solution does not seem to work with \pscircle (unstarred) and other graphics macros (such as \psframe). –  Oh my ghost Jan 24 at 8:14
\documentclass[pstricks,border=12pt,12pt]{standalone}
\SpecialCoor
\begin{document}

\begin{pspicture}[showgrid](-5,-5)(5,5)
  \psforeach{\iA}{-5,-4,..,5}{\qdisk(!
    \iA\space dup 2 mod 0 ne { /SD { pop pop pop } def } if 0 ){2pt}}
\end{pspicture}
\end{document}

or for any possible object:

\documentclass[pstricks,border=12pt,12pt]{standalone}
\makeatletter\let\Modulo\pst@mod\makeatother
\begin{document}

\begin{pspicture}[showgrid](-5,-5)(5,5)
  \psforeach{\iA}{-5,-4,..,5}{%
    \Modulo\iA2\Value
    \ifnum\Value=0 \pscircle(\iA,0){5pt}\fi}
\end{pspicture}

\end{document}
share|improve this answer
1  
Interesting. The original meaning of SD doesn't need to be restored. Why? –  AlexG Jan 23 at 9:04
    
it is used in an own dictionary –  Herbert Jan 23 at 9:13
    
I see. Within \qdisk the current dict is tx@Dict, and the original definition of SD was made outside of it. Thanks. –  AlexG Jan 23 at 9:19
    
Interesting: \qdisk(!\iA\space dup 2 mod 0 ne { /SD {} def } if 0 ){2pt} also works. I applied it to my answer here (click). –  Oh my ghost Jan 24 at 6:33
    
See my updated question. Your solution does not seem to work with \pscircle (unstarred) and other graphics macros (such as \psframe). –  Oh my ghost Jan 24 at 8:13

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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