[Tex/LaTex] Define a new rectangular node with several anchor points in tikz

tikz-pgf

I'd like to define a new node (or maybe a new shape) with many anchor points.
In particular I need of a rectangular shape with up to 15 anchor points on the top and the bottom of the rectangle. That's because I'd like to draw something like this easily:
Two nodes

The red dots are just examples of the position of the possible anchor points, they should not appear in the definitive picture.
If it is possible, all the edges should come out perpendicular to the node (but I guess this must be added as an option in the edges).

\node[mynode,minimum size=5mm] (A1) at (0,0) {Some Text};
\node[mynode,minimum size=5mm,rotate=-45] (A2) at (-1,-1) {};
\draw (A1.t4) -- (A2.b1);
%OR
%\path (A1.t4) edge [out=90,in=90] (A2.b1);

Where t4 and b1 should represent the anchor points (If I understood the syntax correctly).

This is because I'd like to draw pictures of generalized trace diagrams like those in http://elishapeterson.wikidot.com/tikz:diagrams

I found already something similar, but I cannot modify it to make it work for me, e.g.:
https://tex.stackexchange.com/a/75515/58947
https://tex.stackexchange.com/a/33156/58947

I thought the new rectangular node could inherit all the structure of a standard rectangle but adding 15 anchor points e.g. from t1 to t15 for the top and b1 to b15 for the bottom.
But any suggestion is welcome!!
The dream would be that the edges automatically connect to the closer anchor point. Or, even better, the distance between two anchor points change depending on the number of edges connected to the node (namely, if there are only 6 edges connected to the top of the node, they would be separated by l/7 where l is the length of the long side of the rectangle)

Best Answer

The following example defines a new shape rectangle16. It inherits the anchors from the shape rectangle and adds anchors t0 (= north west) to t16 (= north east) and b0 (= south west) to b16 (= south east).

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{topaths}
\usetikzlibrary{calc}
\usetikzlibrary{hobby}

\makeatletter
\newcommand*{\define@anchor@t}[2]{%
  \anchor{t#1}{%
    \pgf@process{\southwest}%
    \pgf@xa=\pgf@x
    \pgf@process{\northeast}%
    \pgf@x=\dimexpr\pgf@xa + (\pgf@x-\pgf@xa)*#1/#2\relax
  }%
}
\newcommand*{\define@anchor@b}[2]{%
  \anchor{b#1}{%
    \pgf@process{\northeast}%
    \pgf@xa=\pgf@x
    \pgf@process{\southwest}%
    \pgf@x=\dimexpr\pgf@x + (\pgf@xa-\pgf@x)*#1/#2\relax
  }%
}
\pgfdeclareshape{rectangle16}{%
  \inheritsavedanchors[from=rectangle]
  \inheritanchorborder[from=rectangle]
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{mid}
  \inheritanchor[from=rectangle]{mid west}
  \inheritanchor[from=rectangle]{mid east}
  \inheritanchor[from=rectangle]{base}
  \inheritanchor[from=rectangle]{base west}
  \inheritanchor[from=rectangle]{base east}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{south east}
  \inheritbackgroundpath[from=rectangle]
  \count@=0 %
  \@whilenum\count@<17 \do{%
    \expandafter\define@anchor@t\expandafter{\the\count@}{16}%
    \expandafter\define@anchor@b\expandafter{\the\count@}{16}%
    \advance\count@\@ne
  }%
}
\makeatother

\begin{document}
  \begin{tikzpicture}
    \node[draw,rectangle16] (N)
      {Rectangular node with additional anchors at the top and bottom};
    \foreach \i in {0, ..., 16} {
      \draw[<-, node font=\footnotesize]
        (N.t\i) -- ++(0, .5) node[above] {t\i}
      ;
      \draw[<-, node font=\footnotesize]
        (N.b\i) -- ++(0, -.5) node[below] {b\i}
      ;
    }
    \node[draw, rectangle16] (ST) at (N.center |- 0, -3) {Some Text};
    \draw
      \foreach \i in {1, ..., 14} { (ST.t\i) -- ++(0, .5) }
      (ST.south east) ++(-2, -1)
      node[
        rectangle16,
        draw,
        rotate=-45,
        minimum width=15mm,
        minimum height=5mm,
      ] (R) {}
      (ST.b1) to (R.t4)
    ;
    \draw[use Hobby shortcut]
      (ST.t15)
      -- ([out angle=90]$(ST.t15) + (0, .1)$)
      .. ($(ST.east) + (.5, 0)$)
      .. ([in angle=-90]$(ST.b15) + (0, -.1)$)
      -- (ST.b15)
    ;
    \fill[
      red,
      radius=.5pt,
    ]
      \foreach \i in {0, ..., 16} {
        \foreach \tb in {t, b} {
          (R.\tb\i) circle[]
        }
      }
    ;
  \end{tikzpicture}
\end{document}

Result

Generalization

The following example defines \declareshaperectxy{<h>}{<v>} with two arguments for the horizontal and vertical number of anchors for the four sides of a rectangular shape and defines the shape with the name rectangle <h>x<v>. For example, after \declareshaperectxy{16}{8} the shape rectangle 16x8 can be used, which provides the additional anchors t0 to t16 at the top, b0 to b16 at the bottom, l0 to l8 at the left side and r0 to r8 at the right side.

\documentclass{article}
\usepackage{tikz}

\makeatletter
\newcommand*{\rectxy@anchor@top}[2]{%
  \anchor{t#1}{%
    \pgf@process{\southwest}%
    \pgf@xa=\pgf@x
    \pgf@process{\northeast}%
    \pgf@x=\dimexpr\pgf@xa + (\pgf@x-\pgf@xa)*#1/#2\relax
  }%
}
\newcommand*{\rectxy@anchor@bottom}[2]{%
  \anchor{b#1}{%
    \pgf@process{\northeast}%
    \pgf@xa=\pgf@x
    \pgf@process{\southwest}%
    \pgf@x=\dimexpr\pgf@x + (\pgf@xa-\pgf@x)*#1/#2\relax
  }%
}
\newcommand*{\rectxy@anchor@left}[2]{%
  \anchor{l#1}{%
    \pgf@process{\northeast}%
    \pgf@ya=\pgf@y
    \pgf@process{\southwest}%
    \pgf@y=\dimexpr\pgf@y + (\pgf@ya-\pgf@y)*#1/#2\relax
  }%
}
\newcommand*{\rectxy@anchor@right}[2]{%
  \anchor{r#1}{%
    \pgf@process{\southwest}%
    \pgf@ya=\pgf@y
    \pgf@process{\northeast}%
    \pgf@y=\dimexpr\pgf@ya + (\pgf@y-\pgf@ya)*#1/#2\relax
  }%
}
\newcommand*{\declareshaperectxy}[2]{%
  \pgfdeclareshape{rectangle #1x#2}{%
    \inheritsavedanchors[from=rectangle]
    \inheritanchorborder[from=rectangle]
    \inheritanchor[from=rectangle]{north}
    \inheritanchor[from=rectangle]{north west}
    \inheritanchor[from=rectangle]{center}
    \inheritanchor[from=rectangle]{west}
    \inheritanchor[from=rectangle]{east}
    \inheritanchor[from=rectangle]{mid}
    \inheritanchor[from=rectangle]{mid west}
    \inheritanchor[from=rectangle]{mid east}
    \inheritanchor[from=rectangle]{base}
    \inheritanchor[from=rectangle]{base west}
    \inheritanchor[from=rectangle]{base east}
    \inheritanchor[from=rectangle]{south}
    \inheritanchor[from=rectangle]{south east}
    \inheritbackgroundpath[from=rectangle]
    \count@=\m@ne
    \@whilenum\count@<#1 \do{%
      \advance\count@\@ne
      \expandafter\rectxy@anchor@top\expandafter{\the\count@}{#1}%
      \expandafter\rectxy@anchor@bottom\expandafter{\the\count@}{#1}%
    }%
    \count@=\m@ne
    \@whilenum\count@<#2 \do{%
      \advance\count@\@ne
      \expandafter\rectxy@anchor@left\expandafter{\the\count@}{#2}%
      \expandafter\rectxy@anchor@right\expandafter{\the\count@}{#2}%
    }%
  }%
}
\makeatother

\declareshaperectxy{16}{8}
\declareshaperectxy{5}{3}

\begin{document}
  \begin{tikzpicture}
    \node[
      draw,
      rectangle 16x8,
      minimum width=80mm,
      minimum height=30mm,
    ] (N) {};
    \foreach \i in {0, ..., 16} {
      \draw[<-, node font=\footnotesize]
        (N.t\i) -- ++(0, .5) node[above] {t\i}
      ;
      \draw[<-, node font=\footnotesize]
        (N.b\i) -- ++(0, -.5) node[below] {b\i}
      ;
    }
    \foreach \i in {0, ..., 8} {
      \draw[<-, node font=\footnotesize]
        (N.l\i) -- ++(-.5, 0) node[left] {l\i}
      ;
      \draw[<-, node font=\footnotesize]
        (N.r\i) -- ++(.5, 0) node[right] {r\i}
      ;
    }
    \node[
      draw,
      rectangle 5x3,
      minimum width=80mm,
      minimum height=30mm,
      at={(0, -55mm)},
    ] (N) {};
    \foreach \i in {0, ..., 5} {
      \draw[<-, node font=\footnotesize]
        (N.t\i) -- ++(0, .5) node[above] {t\i}
      ;
      \draw[<-, node font=\footnotesize]
        (N.b\i) -- ++(0, -.5) node[below] {b\i}
      ;
    }
    \foreach \i in {0, ..., 3} {
      \draw[<-, node font=\footnotesize]
        (N.l\i) -- ++(-.5, 0) node[left] {l\i}
      ;
      \draw[<-, node font=\footnotesize]
        (N.r\i) -- ++(.5, 0) node[right] {r\i}
      ;
    }
  \end{tikzpicture}
\end{document}

Result generalization