Estoy tratando de definir un estilo que establezca to path
de 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 in
los 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 path
estilo, 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):
- 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. - Aplique el
out=x,in=y,relative
a las rutas internamente en lamanifold/.style
operaciónpath to
. No tengo ni idea de cómo hacer esto.
Para 2., probé cosas que encontré en tikzlibrarytopaths.code.tex
, donde, por ejemplo, out
se 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 path
no 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}
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}
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. :)