TikZ personalizado "al camino" con bordes curvos

TikZ personalizado "al camino" con bordes curvos

Estoy tratando de definir un estilo que establezca to pathde manera que se dibuje un “rectángulo curvo” (representación múltiple) cuando coloco \draw (0,0) to[manifold] (5,3).

Hice la forma manualmente especificando inlos outángulos en un sistema de coordenadas absoluto y luego relativo y dibujando las cuatro esquinas usando to. (Primer y segundo ejemplo en MWE).

Puedo dibujar el rectángulo usando un to pathestilo, como se define en el preámbulo. Estoy luchando con dos problemas, donde creo que puedo resolver (1) pero no sé cómo hacerlo (2):

  1. Cómo mover automáticamente las esquinas SE y NW hacia el centro, o (equivalentemente) un 10% hacia las esquinas SW y NE, como en el primer ejemplo. (b se mueve un poco hacia c y a). Probablemente pueda hacerlo con calc y algo de ($(\tikztostart -| \tikztotarget)!0.9!(\tikztostart |- \tikztotarget)$)magia.
  2. Aplique el out=x,in=y,relativea las rutas internamente en la manifold/.styleoperación path to. No tengo ni idea de cómo hacer esto.

Para 2., probé cosas que encontré en tikzlibrarytopaths.code.tex, donde, por ejemplo, outse define como una opción de TikZ que establece \def\tikz@to@out{#1}\tikz@to@switch@on. Poner esto en varios lugares (actualmente en \pgfextra) to pathno funciona. ¿Alguien puede ayudar con esto?

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}

Salida MWE. El medio y el fondo están bien. La parte superior debe ser como la inferior.

Respuesta1

Completamente reimplementado y usando rutas de curvas de Bézier explícitas usando una coordenada (pasada como argumento, que tiene un valor predeterminado) para determinar la curvatura. Ojalá los comentarios expliquen todo.

\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}

ingrese la descripción de la imagen aquí

Respuesta2

No es una respuesta a mis preguntas/problemas específicos, sino una forma diferente, menos TikZ'y, de hacerlo, mediante el uso de una macro simple:

\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;
}

y usarlo como lo \manifold[green,thick]{0,0}{4,3} usa la respuesta de @Mark Wilbrow to path, mi intención original. :)

información relacionada