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.

enter image description here

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pstricks-add}
\begin{document}
\multido{\i=0+30}{12}{%
\begin{pspicture}(-2,-2)(2,2)
    \pscircle{1}
    \pnode(1;\i){R}
    \psset{arrows=->}
    \psline(R)
    \psline[linecolor=blue](R|0,0)
    \psline[linecolor=red](0,0|R)
    \psset{linecolor=gray,linestyle=dashed,linewidth=0.5\pslinewidth,arrows=-,dash=2pt 2pt}
    \psline(R)(R|0,0)
    \psline(R)(0,0|R)
\end{pspicture}}
\end{document}

Does a zero-length line with an arrow make sense? Is it a bug? I hope it is a bug. If it is not a bug, what is the best way to handle this case using a conditional macro in either TeX or PS level?

Apparently, this feature is also adopted by TikZ.

enter image description here

\documentclass[tikz,border=0pt]{standalone}
\usepackage{tikz}
\begin{document}
    \tikzpicture
        \fill[yellow] (-1,-1) -- (-1,1) -- (1,1) -- (1,-1) -- cycle;
        \draw[->] (0,0)--(0,0);
    \endtikzpicture
\end{document}
share|improve this question
1  
Add an epsilon perturbation so that direction is properly defined. –  Aditya Sep 5 '12 at 4:33
    
why should this be a bug? If the user defines an arrow then it is drawn. –  Herbert Sep 5 '12 at 11:54
    
@Herbert: Because it does not make sense. It will be better if the PSTricks core automatically does nothing for zero-length lines. –  Oh my ghost Sep 5 '12 at 11:58
    
that has the user to be decide if it makes sense or not ... –  Herbert Sep 5 '12 at 12:13
    
@Herbert: If the line length with an arrow is measured from the tip of the arrow to the tail of the line then a zero-length line should be invisible. :-) –  Oh my ghost Sep 5 '12 at 12:15

2 Answers 2

up vote 17 down vote accepted

A possible workaround ...

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-node,multido}
\makeatletter
\def\psLine{\pst@object{psLine}}% a special Line 
\def\psLine@i{\pst@getarrows{\begin@OpenObj \pst@getcoors[\psLine@ii}}
\def\psLine@ii{%
    \addto@pscode{
      \ifPst@noCurrentPoint\else\pst@cp\fi    % current point?
      4 copy Pyth2 \psk@arrowlength ge 
        { \psline@iii \tx@Line }% arc and lineto type
        { pop pop pop pop } ifelse }%
  \end@OpenObj}
\makeatother

\begin{document}
\multido{\i=0+30}{12}{%
\begin{pspicture}(-2,-2)(2,2)
    \pscircle{1}
    \pnode(1;\i){R}
    \psset{arrows=->}
    \psLine(0,0)(R)% needs always two pairs of coordinate
    \psLine[linecolor=blue](0,0)(R|0,0)
    \psLine[linecolor=red](0,0)(0,0|R)
    \psset{linecolor=gray,linestyle=dashed,linewidth=0.5\pslinewidth,arrows=-,dash=2pt 2pt}
    \psLine(R)(R|0,0)
    \psLine(R)(0,0|R)
\end{pspicture}}
\end{document}

enter image description here

share|improve this answer
    
Is there another simpler, high level (as opposed to the low level with PSTricks core macro) workaround that I can digest and adopt for my future projects? –  Oh my ghost Sep 5 '12 at 13:01
    
yes, the coordinates are read on TeX level. But it will not be simpler. TeX arithmetic is always a pain –  Herbert Sep 5 '12 at 13:05

In TikZ, you can avoid drawing arrow heads if the last segment of a path has a length of zero by patching the internal \pgf@check@for@arrows macro:

\makeatletter
\def\pgf@check@for@arrows{%
  \pgf@drawarrowsfalse%
  \ifx\pgf@startarrow\pgfutil@empty\else\pgf@drawarrowstrue\fi%
  \ifx\pgf@endarrow\pgfutil@empty\else\pgf@drawarrowstrue\fi%
  \ifdim\pgf@shorten@end@additional=0pt\relax\else\pgf@drawarrowstrue\fi%
  \ifdim\pgf@shorten@start@additional=0pt\relax\else\pgf@drawarrowstrue\fi%
  \ifpgf@drawarrows%
    \pgfsyssoftpath@getcurrentpath\pgf@arrowpath%
    \ifx\pgf@arrowpath\pgfutil@empty%
      \pgf@drawarrowsfalse%
    \else%
      \pgfprocesscheckclosed{\pgf@arrowpath}{\pgf@drawarrowsfalse}%
      %%% New stuff starts here
      % Extract first, second, second last and last points
      \pgfprocesspathextractpoints{\pgf@arrowpath}%
      % If the second last and last points are identical ...
      \ifx\pgfpointsecondlastonpath\pgfpointlastonpath%
        % ... disable the arrow head
        \pgf@drawarrowsfalse%
      \fi%
      %%% New stuff ends here
    \fi%
  \fi%
}
\makeatother

\documentclass[tikz,border=0pt]{standalone}
\usepackage{tikz}

\makeatletter
\def\pgf@check@for@arrows{%
  \pgf@drawarrowsfalse%
  \ifx\pgf@startarrow\pgfutil@empty\else\pgf@drawarrowstrue\fi%
  \ifx\pgf@endarrow\pgfutil@empty\else\pgf@drawarrowstrue\fi%
  \ifdim\pgf@shorten@end@additional=0pt\relax\else\pgf@drawarrowstrue\fi%
  \ifdim\pgf@shorten@start@additional=0pt\relax\else\pgf@drawarrowstrue\fi%
  \ifpgf@drawarrows%
    \pgfsyssoftpath@getcurrentpath\pgf@arrowpath%
    \ifx\pgf@arrowpath\pgfutil@empty%
      \pgf@drawarrowsfalse%
    \else%
      \pgfprocesscheckclosed{\pgf@arrowpath}{\pgf@drawarrowsfalse}%
      \pgfprocesspathextractpoints{\pgf@arrowpath}%
      \ifx\pgfpointsecondlastonpath\pgfpointlastonpath%
        \pgf@drawarrowsfalse%
      \fi%
    \fi%
  \fi%
}
\makeatother

\begin{document}
\foreach \angle in {0,5,...,355}{%
    \begin{tikzpicture}[
        scale=1.5,
        arrow/.style={
            -stealth, thick, line cap=round 
        }
    ]
        \fill [white] (-1.02,-1.02) rectangle (1.02, 1.02);
        \draw [gray, densely dashed] (0:{cos(\angle)}) |- (90:{sin(\angle)});
        \draw (0,0) circle [radius=1];
        \draw [blue, arrow] (0,0) -- (0:{cos(\angle)});
        \draw [red, arrow] (0,0) -- (90:{sin(\angle)});
        \draw [black, arrow] (0,0) -- (\angle:1);
    \end{tikzpicture}%
}
\end{document}
share|improve this answer

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.