TikZ benutzerdefinierter „zu Pfad“ mit gekrümmten Kanten

TikZ benutzerdefinierter „zu Pfad“ mit gekrümmten Kanten

Ich versuche, einen Stil zu definieren, der to pathso eingestellt ist, dass ein „kurviges Rechteck“ (Mannigfaltigkeitsdarstellung) gezeichnet wird, wenn ich eingebe \draw (0,0) to[manifold] (5,3).

Ich habe die Form manuell erstellt, indem ich in einem absoluten und dann relativen Koordinatensystem Winkel angegeben und die vier Ecken mit gezeichnet habe in. (Erstes und zweites Beispiel in MWE.)outto

Ich kann das Rechteck mit einem to pathStil zeichnen, wie in der Präambel definiert. Ich kämpfe mit zwei Problemen, bei denen ich denke, dass ich (1) lösen kann, aber nicht weiß, wie ich (2) machen soll:

  1. Wie verschiebt man automatisch die SE- und NW-Ecken zur Mitte oder (entspricht) 10 % zu den SW- und NE-Ecken, wie im ersten Beispiel. (b wird dort ein bisschen zu c und a verschoben). Das kann ich wahrscheinlich mit Kalk und etwas ($(\tikztostart -| \tikztotarget)!0.9!(\tikztostart |- \tikztotarget)$)Magie machen.
  2. Wenden Sie dies intern im Vorgang out=x,in=y,relativeauf die Pfade an . Ich habe keine Ahnung, wie das geht.manifold/.stylepath to

Zu 2. habe ich Dinge ausprobiert, die ich in gefunden habe tikzlibrarytopaths.code.tex, wo zB outals TikZ-Option definiert ist, die festlegt \def\tikz@to@out{#1}\tikz@to@switch@on. Dies an verschiedenen Stellen (derzeit in \pgfextrain to path) zu platzieren, funktioniert nicht. Kann mir jemand dabei helfen?

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-Ausgabe. Mitte und unten sind in Ordnung. Oben muss wie unten sein.

Antwort1

Komplett neu implementiert und mit expliziten Bézierkurvenpfaden unter Verwendung einer Koordinate (als Argument übergeben, die einen Standardwert hat), um die Krümmung zu bestimmen. Hoffentlich erklären die Kommentare alles.

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

Bildbeschreibung hier eingeben

Antwort2

Keine Antwort auf meine spezifischen Fragen/Probleme, sondern eine andere, weniger TikZ-mäßige Möglichkeit, dies mithilfe eines einfachen Makros zu tun:

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

und es so zu verwenden, wie \manifold[green,thick]{0,0}{4,3} es in der Antwort von @Mark Wilbrow verwendet wird to path, was meine ursprüngliche Absicht war. :)

verwandte Informationen