3

I am looking to draw a 'teardrop' or 'droplet' shape to use as a shape within TikZ-network. More specifically, I would like to recreate the following tensor network:

enter image description here

and the teardrop with the "+" is giving me some trouble. I have seen some discussion here that draws a single 'teardrop', but I am not sure how to create such a shape for use within a graph/network (preferably using TikZ-network). I know the teardrop is just half a circle and half a (tilted) rectangle/square, but I cannot figure out how to make it into a shape that can be easily rotated and used as a node. Any help is appreciated.

2
  • 1
    Implementing this as a proper node will be interesting as a node declaration is not trivial when it comes to defining the anchor border (though not as hard as with more complex shapes). The easiest solution would be to draw the edges first and then place a teardrop on top of it with a fill=white covering the edges. We can even use a circle node with the + first to measure the needed circumference. Commented Oct 20, 2023 at 13:57
  • If you want to do it right, see section 106.5 (page 1143) on how to create a new shape. Keep in mind that TikZ changes the node size to fit the text inside. Commented Oct 20, 2023 at 14:11

1 Answer 1

3

The teardrop in your image, luckily, doesn't look like a true teardrop but just a right angled corner on the side of a circle.

Instead of defining a new shape which would be the preferred way but will not be trivial for the anchor border – though, we can simply define a specific anchor for that teardrop corner and use that explicitly when drawing edges – we can reuse the circle shape by replacing its background path with a custom path.

Unless you need to connect this node on the straight parts of the teardrop tip and are okay with having to specify the anchor teardrop separately when connecting edges to the teardrop tip, this is much easier than defining your own shape.

Note though, that with this implementation you can't use the teardrop anchor when placing the node and it will also not be available for the aliases. If this is needed, a few adjustments have to be made.

Code

\documentclass[tikz]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows.meta, cd}
\makeatletter
%%% Adding anchors to node after it has been created
%%% does not apply to the aliases
\tikzset{% https://tex.stackexchange.com/a/676090
  add anchor to node/.code n args={3}{%
    \edef\tikz@temp##1{% \tikz@pp@name/\tikzlastnode needs to be expanded
      \noexpand\pgfutil@g@addto@macro\expandafter\noexpand\csname pgf@sh@ma@\tikz@pp@name{#1}\endcsname{%
        \def\expandafter\noexpand\csname pgf@anchor@\csname pgf@sh@ns@\tikz@pp@name{#1}\endcsname @#2\endcsname{##1}}}%
    \tikz@temp{#3}}}

\tikzset{% an “arrow” pic for putting arrow tips along edges
  pics/arrow/.default=>,
  pics/arrow/.style={
    /tikz/sloped, /tikz/allow upside down, foreground code=, background code=,
    setup code=\pgfarrowtotallength{#1}\pgftransformxshift{+.5\pgf@x},
    code=\pgfarrowdraw{#1}},
  replace bg path/.code=\tikz@addoption % https://tex.stackexchange.com/a/697638
    {\pgfutil@namedef{pgf@sh@bg@\tikz@shape}{#1}}}
\makeatother
\newcommand*\tikzinsertpath[1]{\pgfkeysvalueof{/tikz/insert path/.@cmd}#1\pgfeov}
\tikzset{replace bg path tikz/.style={replace bg path=\tikzinsertpath{#1}}}
%%%
%%% the teardrop “shape” based on a circle
%%% with a custom path and an extra anchor which is only accessible
%%% after the node has been created and not with the node's aliases
\tikzset{
  xy/.code=\pgfmathparse{#1}%
    \tikzset{style/.expanded={x=+\pgfmathresult pt, y=+\pgfmathresult pt}},
  teardrop shape/.style={
    shape=circle,
    append after command={[add anchor to node={\tikzlastnode}{teardrop}
      {\pgfpointadd{\centerpoint}{\pgfpointpolar{#1}{1.414*\radius}}}]},
    replace bg path tikz={
      \bgroup % keep the shift local
        \pgfextra{\pgftransformshift{\centerpoint}}
        [xy={\radius-max(\pgfkeysvalueof{/pgf/outer xsep},%
                         \pgfkeysvalueof{/pgf/outer ysep})}]
        ({#1+45}:1) arc[start angle={#1+45}, delta angle=270, radius=1]
        -- ({#1}:sqrt 2) -- cycle
      \egroup}}}
%%%
%%% TikZ-CD settings
\tikzcdset{
  tensor/.style={
    /tikz/_/.style={path only, shape=asymmetrical rectangle}, % for the =
    /tikz/c/.style={shape=coordinate},                 % placeholder/empty node
    arrows={thick, /tikz/arrows=-}, arrow style=tikz, >=Triangle,
    row sep=1em, column sep=1em,
    Tri/.style={/tikz/every to/.append style={edge node={pic[{#1}]{arrow}}}},
    /tikz/teardrop/.style={% to be used inside |[…]|
      teardrop shape={##1}, inner sep=+0pt,
      text height=, text width=, text depth=, align=none},
    from teardrop/.style={% to be used when edge is straight out of teardrop tip
      start anchor=teardrop,
      /utils/exec=\pgfsetarrowsstart{Triangle Cap[cap angle=90, reversed]},
      shorten <=+-.5\pgflinewidth},
    to   teardrop/.style={%  to be used when edge is straight into teardrop tip
      end anchor=teardrop,
      /utils/exec=\pgfsetarrowsend{Triangle Cap[cap angle=90, reversed]},
      shorten >=+-.5\pgflinewidth},
    cells={nodes={
        draw, thick, inner sep=+.2em, anchor=center, shape=circle,
        text width=width("$W$"),  align=center,
        text height=+.7em, text depth=+0pt}}},
  color shortcuts/.style args={#1#2}{/tikz/#1/.style={fill=#1#2!50}},
  color shortcuts'/.style args={#1:#2}{/tikz/#1/.style={fill=#2!50}}}
\begin{document}
\begin{tikzcd}[tensor, color shortcuts/.list={green, blue, teal}]
|[g]| h \rar
  & |[_]| =
    &[-.8em] |[b]| x \rar
      & |[t]| W \rar
        & |[teardrop=0]| + \ar[from teardrop, rr, Tri, "\sigma" xshift=.3ex] \dar
          & & |[c]| \\
  & & & & |[t]| b
\end{tikzcd}
\end{document}

Output

enter image description here

2
  • The argument of teardrop shape and thus teardrop is the direction of the “drop”. Commented Oct 20, 2023 at 15:23
  • Thanks, looks really good. I will play around with it on how to integrate it within TikZ-network. Commented Oct 23, 2023 at 9:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .