7

I am trying to define a style that sets to path such that a “curvy rectangle” (manifold representation) is drawn when I put \draw (0,0) to[manifold] (5,3).

I have manually made the shape by specifying in and out angles in an absolute and then relative coordinate system and drawing the four corners using to. (First and second example in MWE.)

I can draw the rectangle using a to path style, as defined in the preamble. I am struggling with two problems, where I think I can solve (1) but don't know how to do (2):

  1. How to automatically move the SE and NW corners towards the centre, or (equivalently) 10% towards the SW and NE corners, like in the first example. (b there is moved a bit towards c and a). I can probably do that with calc and some ($(\tikztostart -| \tikztotarget)!0.9!(\tikztostart |- \tikztotarget)$) magic.
  2. Apply the out=x,in=y,relative to the paths internally in the manifold/.style's path to operation. I have no idea how to do this.

For 2., I tried things I found in tikzlibrarytopaths.code.tex, where e.g. out is defined as a TikZ option that sets \def\tikz@to@out{#1}\tikz@to@switch@on. Putting this in various places (currently in \pgfextra in to path) doesn't work. Can anybody help with this?

MWE

\documentclass[tikz]{standalone}

\makeatletter
\tikzset{manifold/.style={
  to path={
    \pgfextra{
    \def\tikz@to@out{20}\tikz@to@switch@on
    }
    (\tikztostart) -- (\tikztostart -| \tikztotarget)
    -- (\tikztotarget)
    -- (\tikztostart |- \tikztotarget)
    -- cycle
    (\tikztotarget)
    \tikztonodes
  }
}}
\makeatother

\begin{document}

\begin{tikzpicture}[every node/.style={opacity=0.5,color=cyan}]
  \draw[line width=0.5pt,dotted,red] (-1,-3) grid (5,7);

  % base manifold: absolute in/out angles
  \draw[thick] (0,0) node{a}
    to[out=-10,in=170] (4,0.5) node{b}
    to[out=70,in=-130] (5,3) node{c}
    to[out=170,in=-10] (1,2.5) node{d}
    to[out=-130,in=70] cycle;

  % base manifold: relative in/out angles: all the same
  \begin{scope}[shift={(0,-3)},out=-20,in=160,relative]
    \draw (0,0) to (4,0.5) to (5,3) to (1,2.5) to cycle;
  \end{scope}

  % base manifold: to path style
  \begin{scope}[shift={(0,3)}]
    \draw[red] (0,0) to[manifold] (5,3);
  \end{scope}
\end{tikzpicture}
\end{document}

MWE output. Middle and bottom are fine. Top must be like bottom.

2 Answers 2

5

Completely reimplemented and using explicit Bézier curve paths using a coordinate (passed as argument, which has a default value) to determine the curviness. Hopefully comments explain everything.

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{calc}
\tikzset{manifold/.style={to path={
  % Create new coordinates to save typing
  (\tikztostart) coordinate (@1)
  (\tikztostart |- \tikztotarget) coordinate (@2)
  (\tikztotarget) coordinate (@3)
  (\tikztostart -| \tikztotarget) coordinate (@4)
  % Get 'transformed' points
  (@1) coordinate (@@1)
  ($(@2)!0.1!(@4)$) coordinate (@@2)
  (@3) coordinate (@@3)
  ($(@4)!0.1!(@2)$) coordinate (@@4)
  % Calculate \manifoldsize for scaling
  let \p1=(@1),\p2=(@3),\n1={veclen(\x2-\x1,\y2-\y1)} in
  \pgfextra{\edef\manifoldsize{\n1}} 
  % Use coordinate passed in as #1
  let \p1=#1 in
  %
  (@@1) .. controls ++( \x1, \y1) and ++(-\x1,-\y1) .. 
  (@@2) .. controls ++( \x1,-\y1) and ++(-\x1, \y1) ..
  (@@3) .. controls ++(-\x1,-\y1) and ++( \x1, \y1) ..
  (@@4) .. controls ++(-\x1, \y1) and ++( \x1,-\y1) .. cycle (@@3)
}}, manifold/.default={(45:\manifoldsize/4)}}
\begin{document}
\begin{tikzpicture}[ultra thick, line join=round]
\draw [purple] (-2,-2) to [manifold] (5,4);
\draw [orange] (0,0) to [manifold] (3,2);
\end{tikzpicture}
\end{document}

enter image description here

3
  • Just curiosity: Where is documented that @ is a letter in tikzset and doesn't need to be protected with \makeatletter \makeatother? It's the first time I see it.
    – Ignasi
    Commented Feb 11, 2016 at 17:09
  • 1
    @Ignasi it isn't documented, I am simply exploiting the fact that in normal circumstances @ is a legitimate character in a node name, and tend to use such names for "throw away" coordinates that aren't required outside of the path drawing. The technical reason is that macros which have node names defined and called surrounded with \csname and \endcsname. In these cases it doesn't matter whether @ is a letter category code or other. Commented Feb 11, 2016 at 18:39
  • Thanks! It allows me to draw manifolds, although doesn't really answer why/how to do my problem with other approach, but I'm afraid that has to do with trying to use a [curve to] which sets a different to path so it might be better not to go there… See below for how I had in the meantime made a macro to do it, but this is a more TikZ way of doing it.
    – Geert F
    Commented Feb 11, 2016 at 22:39
1

Not an answer to my specific questions/problems, but a different, less-TikZ'y way of doing it, by using a simple macro:

\newcommand\manifold[3][]{
  \draw[every to/.style={out=-20,in=160,relative},#1] (#2) 
  to ($(#2 -| #3)!0.2!(#2 |- #3)$)
  to (#3)
  to ($(#2 -| #3)!0.8!(#2 |- #3)$)
  to cycle;
}

and using it like \manifold[green,thick]{0,0}{4,3} Answer by @Mark Wilbrow uses to path, my original intent. :)

You must log in to answer this question.

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