# Rounded corners don't work properly in custom decoration

I want to create some chemical Lewis structures with TikZ - I can't use chemfig for this since I need to draw the atoms according to their coordinates - and need to define some custom bond types, for example wedge-shaped bonds and dashed-wedge-shaped bonds. Decorations seemed like the natural way to do this (if someone knows a better way, I'm open to suggestions) and managed to get something working. I've done it in such a way that the bond is surrounded by some white-space in order to make it look right in situations where two bonds might overlap (I've colored the white-space blue to make it visible in my example code). To make it look a little prettier I wanted to use rounded corners but unfortunately these don't seem to work properly in my decoration. How can I get the rounded corners to work?

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{decorations}

\begin{document}

\begin{tikzpicture}

\newlength{\dashedwedgelen}
\setlength{\dashedwedgelen}{5pt}

\newlength{\wedgeheight}
\setlength{\wedgeheight}{2.5pt}

\pgfmathsetmacro\startheight{\wedgeheight/5}
\pgfmathsetmacro\whitespace{\wedgeheight/2}
\pgfmathsetmacro\dashgapratio{0.3}

\pgfdeclaredecoration{dashed wedge}{initial}
{
\state{initial}[
width=0.0,
persistent precomputation={
\pgfmathsetmacro\dashseglen{(\pgfdecoratedpathlength - \dashgapratio*\dashedwedgelen) / floor((\pgfdecoratedpathlength - \dashgapratio*\dashedwedgelen)/\dashedwedgelen)}},
next state=body
]
{
% surrounding white space
\color{blue}
\pgfpathmoveto{\pgfpoint{0}{\startheight + \whitespace}}
\pgfpathlineto{\pgfpoint{\pgfdecoratedpathlength}{\wedgeheight + \whitespace}}
\pgfpathlineto{\pgfpoint{\pgfdecoratedpathlength}{-(\wedgeheight + \whitespace)}}
\pgfpathlineto{\pgfpoint{0}{-(\startheight + \whitespace)}}
\pgfpathlineto{\pgfpoint{0}{\startheight + \whitespace}}
\pgfclosepath
\pgfusepath{fill, stroke}
\pgfpathmoveto{\pgfpointdecoratedinputsegmentlast}
}
\state{body}[width=\dashseglen]
{
% computations
\pgfmathsetmacro\segwidth{\dashgapratio*\dashseglen}
\pgfmathsetmacro\segstartheight{\startheight + (\wedgeheight - \startheight)*(\pgfdecoratedcompleteddistance) / \pgfdecoratedpathlength}
\pgfmathsetmacro\segendheight{\startheight + (\wedgeheight - \startheight)*(\pgfdecoratedcompleteddistance + \dashgapratio*\dashseglen) / \pgfdecoratedpathlength}
% drawing
\pgfpathmoveto{\pgfpoint{0}{\segstartheight}}
\pgfpathlineto{\pgfpoint{\segwidth}{\segendheight}}
\pgfpathlineto{\pgfpoint{\segwidth}{-\segendheight}}
\pgfpathlineto{\pgfpoint{0}{-\segstartheight}}
\pgfpathlineto{\pgfpoint{0}{\segstartheight}}
\pgfpathclose
}
\state{final}
{
% computations
\pgfmathsetmacro\segwidth{\dashgapratio*\dashseglen}
\pgfmathsetmacro\segstartheight{\startheight + (\wedgeheight - \startheight)*(\pgfdecoratedcompleteddistance) / \pgfdecoratedpathlength}
\pgfmathsetmacro\segendheight{\startheight + (\wedgeheight - \startheight)*(\pgfdecoratedcompleteddistance + \dashgapratio*\dashseglen) / \pgfdecoratedpathlength}
% drawing
\pgfpathmoveto{\pgfpoint{0}{\segstartheight}}
\pgfpathlineto{\pgfpoint{\segwidth}{\segendheight}}
\pgfpathlineto{\pgfpoint{\segwidth}{-\segendheight}}
\pgfpathlineto{\pgfpoint{0}{-\segstartheight}}
\pgfpathlineto{\pgfpoint{0}{\segstartheight}}
\pgfpathclose
\pgfmoveto{\pgfpointdecoratedpathlast}
}
}

\node (x) at (0,0) [rectangle, rounded corners=0.8mm, fill = blue, inner sep=0.1mm, scale=2.5] {Ti};
\node (y) at (1.5,0.) [rectangle, rounded corners=0.8mm, fill = blue, inner sep=0.1mm, scale=2.5] {L};

\fill [red, decorate, decoration=dashed wedge, rounded corners=0.5pt] (x) -- (y);

\end{tikzpicture}

\end{document}


• I think the problem is that you explicitly draw a line and close the path. If you remove the \pgfpathlineto before each \pgfclosepath then the problem may go away. – Mark Wibrow Sep 12 '14 at 12:27
• @MarkWibrow Thank you very much. This indeed works like a charm. – Philipp Sep 12 '14 at 17:47

The problem is that you explicitly draw a line and close the path. If you remove the \pgfpathlineto before each \pgfclosepath then the problem goes away.

It is also possible to make the code a teensy bit more efficient by using \pgfqpoint (which doesn't use the math parser) and \pgfmathsetlengthmacro (to make sure parsed expressions stored in macros end in pt).

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{decorations}

\begin{document}

\begin{tikzpicture}

\newlength{\dashedwedgelen}
\setlength{\dashedwedgelen}{5pt}

\newlength{\wedgeheight}
\setlength{\wedgeheight}{2.5pt}

\pgfmathsetmacro\startheight{\wedgeheight/5}
\pgfmathsetmacro\whitespace{\wedgeheight/2}
\pgfmathsetmacro\dashgapratio{0.3}

\pgfdeclaredecoration{dashed wedge}{initial}
{
\state{initial}[
width=0.0,
persistent precomputation={
\pgfmathsetmacro\dashseglen{(\pgfdecoratedpathlength - \dashgapratio*\dashedwedgelen) / floor((\pgfdecoratedpathlength - \dashgapratio*\dashedwedgelen)/\dashedwedgelen)}%
%
\pgfmathsetlengthmacro\wedgeheight{\wedgeheight}%
\pgfmathsetlengthmacro\startheight{\startheight}%
\pgfmathsetlengthmacro\whitespace{\whitespace}%
},
next state=body
]
{
% surrounding white space
\pgfmathsetlengthmacro\beginheight{\startheight+\whitespace}
\pgfmathsetlengthmacro\endheight{\wedgeheight + \whitespace}
\pgfpathmoveto{\pgfqpoint{0pt}{\beginheight}}
\pgfpathlineto{\pgfqpoint{\pgfdecoratedpathlength}{\endheight}}
\pgfpathlineto{\pgfqpoint{\pgfdecoratedpathlength}{-\endheight}}
\pgfpathlineto{\pgfqpoint{0pt}{-\beginheight}}
\pgfclosepath
\pgfsetfillcolor{blue}
\pgfsetstrokecolor{blue}
\pgfusepath{fill, stroke}
}
\state{body}[width=\dashseglen]
{
% computations
\pgfmathsetlengthmacro\segwidth{\dashgapratio*\dashseglen}
\pgfmathsetlengthmacro\segstartheight{\startheight + (\wedgeheight - \startheight)*(\pgfdecoratedcompleteddistance) / \pgfdecoratedpathlength}
\pgfmathsetlengthmacro\segendheight{\startheight + (\wedgeheight - \startheight)*(\pgfdecoratedcompleteddistance + \dashgapratio*\dashseglen) / \pgfdecoratedpathlength}
% drawing
\pgfpathmoveto{\pgfqpoint{0pt}{\segstartheight}}
\pgfpathlineto{\pgfqpoint{\segwidth}{\segendheight}}
\pgfpathlineto{\pgfqpoint{\segwidth}{-\segendheight}}
\pgfpathlineto{\pgfqpoint{0pt}{-\segstartheight}}
\pgfpathclose
}
\state{final}
{
% computations
\pgfmathsetlengthmacro\segwidth{\dashgapratio*\dashseglen}
\pgfmathsetlengthmacro\segstartheight{\startheight + (\wedgeheight - \startheight)*(\pgfdecoratedcompleteddistance) / \pgfdecoratedpathlength}
\pgfmathsetlengthmacro\segendheight{\startheight + (\wedgeheight - \startheight)*(\pgfdecoratedcompleteddistance + \dashgapratio*\dashseglen) / \pgfdecoratedpathlength}
% drawing
\pgfpathmoveto{\pgfqpoint{0pt}{\segstartheight}}
\pgfpathlineto{\pgfqpoint{\segwidth}{\segendheight}}
\pgfpathlineto{\pgfqpoint{\segwidth}{-\segendheight}}
\pgfpathlineto{\pgfqpoint{0pt}{-\segstartheight}}
\pgfpathclose
}
}

\node (x) at (0,0) [rectangle, rounded corners=0.8mm, fill = blue, inner sep=0.1mm, scale=2.5] {Ti};
\node (y) at (1.5,0.) [rectangle, rounded corners=0.8mm, fill = blue, inner sep=0.1mm, scale=2.5] {L};

\fill [red, decorate, decoration=dashed wedge, rounded corners=0.5pt] (x) -- (y);

\end{tikzpicture}

\end{document}