Te doy la bienvenida a nuestro sitio web, ahora vas a encontrar la resolución de lo que estabas buscando.
Solución:
¿Como esto?
Aunque debo confesar que todavía no tengo la solución general, para este caso particular el efecto se logró dibujando la flecha de TN a TM en lugar de TM a TN. De esta manera se dibujó la flecha después el horizontal. Y por supuesto que usé leftarrow
para obtener la punta de flecha correcta.
documentclassarticle
usepackagetikz-cd
begindocument
[
begintikzcd[ampersand replacement=&,column sep=small]
GM arrow[pos=0.75]rrmodels_M
arrow[two heads,swap]dre_M
arrow[swap]ddGf
& &
R^FM
arrowddR^Ff \
& T M
arrow[tail,swap]rum_M
& \
GN arrow[pos=0.75,crossing over]rrmodels_N
arrow[two heads,swap]dre_N
& & R^FN \
& T N
arrow[leftarrow,pos=0.25,crossing over]uuT f % <<----- HERE
arrow[tail,swap]rum_N &
endtikzcd
]
enddocument
Actualización: una solución más general
La solución anterior es ad hoc y funciona solo para este ejemplo en particular. La solución general permitiría dibujar cualquier flecha adicional entre dos nodos del diagrama conmutativo ya compuesto.
La idea es la siguiente. Ya que internamente tikzcd
usa un matrix of nodes
para componer cada nodo del diagrama, ¿por qué no sería posible usar esos nodos como parte de una ruta dibujada después del diagrama?
La idea es razonable, pero hay algunos problemas aquí:
- ¿Cuáles son los nombres de cada nodo en el diagrama? ¿Sería posible usar la sintaxis
[(name)]
normalmente permitido dentro de un tikzmatrix of nodes
? Respuesta: no, no es posible, eso rompería el código delarrow
macro, que se basa en los nombres generados automáticamente para los nodos. - Entonces, ¿hay nombres generados automáticamente? ¿Cuáles son esos nombres? Respuesta: Todos comienzan con
tikzmatrixname
y tener el sufijo-row-column
. Entonces, por ejemplo, el primer nodo de este diagrama (con la etiqueta GM) seríatikzmatrixname-1-1
, el nodo central (TM) estikzmatrixname-2-2
, etcétera. -
Entonces sería posible agregar
draw (tikzmatrixname-1-1) to[bend left] (tikzmatrixname-2-2)
; por ejemplo, después de que se hace la matriz? es decir: esto por ejemplo:begintikzcd[ampersand replacement=&,column sep=small] GM arrow[pos=0.75]rrmodels_M [...] arrow[tail,swap]rum_N & % After all nodes are in the matris, draw some extra arrows draw[bend left] (tikzmatrixname-1-1) to[bend left] (tikzmatrixname-2-2); endtikzcd
Respuesta: Lamentablemente, la respuesta es no, esto no es posible debido a la forma
tikcd
maneja el diagrama. Dentro detikzcd
medio ambiente, sorprendentemente suficiente, notikz
se pueden emitir comandos. De hecho, todostikz
Los comandos no están definidos, porque eltikzcd
medio ambiente no es atikzpicture
medio ambiente. Esto explica por qué no puede usarnode
,draw
ni ningún otro comando.Qué
tikzcd
lo que hace es, cada vez que usa el comandoarrow
u otro equivalente, para calcular el apropiadopath
comando, pero en lugar de "ejecutarlo", se almacena en una lista con todas las otras rutas resultantes de otrasarrow
comandos. Al final detikzcd
medio ambiente, untikzpicture
se crea, que contiene elmatrix of nodes
, y dentro de esa imagen, finalmente la lista depath
se ejecutan los comandos, dibujando todas las flechas.
¿Entonces, qué podemos hacer?
Seria genial si tikzcd
proporcionó una especie de drawAtTheEnd
comando, que permite almacenar cualquier comando de dibujo tikz de la misma manera que la lista de rutas, y ejecutar los comandos almacenados al final de la tikzcd
medio ambiente. De esta manera podríamos agregar otras flechas, decoraciones, definir coordenadas de nodo con overlay, remember picture
para acceder desde otras partes de la página, etc.
Mientras tanto, codifiqué un truco que permite insertar una nueva ruta en la lista interna utilizada por tikzcd. La macro se llama latearrow
y se necesitan cuatro argumentos:
- Las opciones tikz de la flecha (puedes pasar colores,
to path
s,pos
, etc - El nombre del nodo inicial, sin el
tikzmatrixnode
parte. Es decir: para referirse al nodo GM lo llamarás1-1
, el nodo TM será2-2
, etcétera. - El nombre del nodo final (también sin el
tikzmatrixnode
parte) - El texto de la etiqueta en la flecha.
Usando esa macro, primero puede dibujar su diagrama conmutativo completo, excepto la flecha de TM a TN, y luego agregar esa flecha al final con la sintaxis:
latearrowpos=0.75,crossing over2-24-2T f
Como se dijo, es un truco rápido y sucio, y no usa la misma sintaxis que otras flechas, no permite opciones de estilo para la etiqueta y no estoy seguro de si rompería algo, pero aparentemente funciona. Aquí está el código:
documentclassarticle
usepackagetikz-cd
makeatletter
deflatearrow#1#2#3#4%
[email protected]
expandafter[email protected]path[/tikz/commutative diagrams/every arrow,#1]%
globaledef[email protected]%
the[email protected]%
(tikzmatrixname-#2)% noexpand[email protected])%
to%
node[/tikz/commutative diagrams/every label] $#4$
(tikzmatrixname-#3)% noexpand[email protected])
;
makeatother
begindocument
[
begintikzcd[ampersand replacement=&,column sep=small]
GM arrow[pos=0.75]rrmodels_M
arrow[two heads,swap]dre_M
arrow[swap]ddGf
& &
R^FM
arrowddR^Ff \
& T M
arrow[tail,swap]rum_M
& \
GN arrow[pos=0.75]rrmodels_N
arrow[two heads,swap]dre_N
& & R^FN \
& T N
arrow[tail,swap]rum_N &
latearrowpos=0.75,crossing over2-24-2T f
latearrowred, bend left1-12-2x
endtikzcd
]
enddocument
Tenga en cuenta que agregué un blue
opción a esta flecha, para demostrar que funciona. Solo por diversión, agregué también una "flecha tardía" curva roja de GM a TM. Este es el resultado:
La funcionalidad de la respuesta principal se puede obtener directamente usando tikzcd colocando el siguiente comando al final del diagrama:
arrow[from=2-2, to=4-2, pos=0.75, crossing over, "T f"']
Entonces el ejemplo completo sería:
documentclassarticle
usepackagetikz-cd
begindocument
[
begintikzcd[ampersand replacement=&,column sep=small]
GM arrow[pos=0.75]rrmodels_M
arrow[two heads,swap]dre_M
arrow[swap]ddGf
& &
R^FM
arrowddR^Ff \
& T M
arrow[tail,swap]rum_M
& \
GN arrow[pos=0.75,crossing over]rrmodels_N
arrow[two heads,swap]dre_N
& & R^FN \
& T N
arrow[tail,swap]rum_N &
arrow[from=2-2, to=4-2, pos=0.75, crossing over, "T f"']
endtikzcd
]
enddocument
Una solución al definir un comando latearrow
Similar a la solución dada por JLDiaz, puede definir un comando latearrow
. Mi versión de latearrow
está configurado para que tikzcd imprima primero las flechas normales en el orden en que aparecen, luego las latearrow
s en el orden en que aparecen. La sintaxis de latearrow
es exactamente idéntica a la sintaxis de arrow
.
Tenga en cuenta que esto maneja tanto la sintaxis nueva como la antigua correctamente, por lo que puede usar la sintaxis antigua:
latearrow[pos=0.75, crossing over,swap]ddT f
o la nueva sintaxis:
latearrow[dd,pos=0.75, crossing over,"T f"']
y ambos funcionan (hacer que esto funcione para la sintaxis anterior agregó 8 llamadas a patchcmd
y tres let
's).
documentclassarticle
usepackageetoolbox
usepackagetikz-cd
makeatletter
patchcmd[email protected]
globallet[email protected][email protected]
globallet[email protected][email protected]
globallet[email protected][email protected]
% For some reason this patchcmd call fails =(
%patchcmdendtikzcd[email protected][email protected][email protected]
% So we have to copy the whole original version of endtikzcd
defendtikzcd%
pgfmatrixendrowegroup%
pgfextragloballettikzcdmatrixnametikzlastnode;%
tikzcdsetthepgfmatrixcurrentrow-row diagram/.try%
begingroup%
pgfkeys% `quotes' library support
/handlers/first char syntax/the character "/.initial=[email protected]@quotes,%
/tikz/edge quotes mean=%
edge node=node [execute at begin node=[email protected]$fi,%$
execute at end node=[email protected]$fi,%$
/tikz/commutative diagrams/.cd,every label,##2]##1%
let[email protected]errmessage% improve error messages
deferrmessage##1[email protected]##1^^J...^^Jl.[email protected]space%
I think the culprit is a tikzcd arrow in cell
[email protected][email protected]%
[email protected]@[email protected]%
[email protected][email protected] % I just added [email protected]
endgroup%
endtikzpicture%
ifnum0=`fi
letlatearrow[email protected] % patchcmd comes through for us here.
let[email protected]@arrow[email protected]@arrow
let[email protected]@new[email protected]@new
let[email protected]@old[email protected]@old
let[email protected]@getlabel[email protected]@getlabel
patchcmdlatearrow[email protected][email protected]
patchcmdlatearrow[email protected]@arrow[email protected]@arrow
patchcmdlatearrow[email protected]@old[email protected]@old
patchcmd[email protected]@arrow[email protected]@old[email protected]@old
patchcmd[email protected]@arrow[email protected]@new[email protected]@new
patchcmd[email protected]@old[email protected]@getlabel[email protected]@getlabel
patchcmd[email protected]@old[email protected]@getlabel[email protected]@getlabel
patchcmd[email protected]@old[email protected]@new[email protected]@new
patchcmd[email protected]@getlabel[email protected]@getlabel[email protected]@getlabel
patchcmd[email protected]@getlabel[email protected]@getlabel[email protected]@getlabel
patchcmd[email protected]@getlabel[email protected]@new[email protected]@new
patchcmd[email protected]@new[email protected][email protected]
def[email protected]
makeatother
begindocument
[
begintikzcd[ampersand replacement=&,column sep=small]
GM arrow[pos=0.75]rrmodels_M
arrow[two heads,swap]dre_M
arrow[swap]ddGf
& &
R^FM
arrowddR^Ff \
& T Mlatearrow[pos=0.75, crossing over,swap]ddT f
% Here's the latearrow call. This arrow will go on top.
arrow[tail,swap]rum_M
& \
GN arrow[pos=0.75,crossing over]rrmodels_N
arrow[two heads,swap]dre_N
& & R^FN \
& T N
arrow[tail,swap]rum_N &
endtikzcd
]
enddocument
El código funciona 1) cambiando endtikzcd
para que ponga los dos [email protected]
y [email protected]
en el diagrama y 2) copiando el arrow
código pero modificándolo para almacenar las rutas en [email protected]
en lugar de [email protected]
. Porque al final se usan en el orden
[email protected][email protected]
, todos los caminos creados usando el normal arrow
El comando se imprime primero, y luego las rutas usando latearrow
, cada uno en el orden en que aparecen.
Por alguna razón el patchcmd
la llamada que debería hacer el paso 1 falla, así que simplemente copié la definición completa de endtikzcd
y agregué el comando adicional que necesitaba.
Hago el paso 2 copiando todos los comandos internos utilizados en arrow
y luego usar un montón de llamadas para patchcmd
para vincularlos entre sí y para reemplazar la macro de rutas guardadas. Porque arrow
tiene una sintaxis excepcionalmente complicada, hay cuatro comandos internos, cada uno de los cuales necesita hasta tres sustituciones.
Obviamente, las actualizaciones de tikzcd pueden romper este código, pero es muy simple, por lo que no debería ser difícil de arreglar.
Editar: La versión que publiqué ayer estaba rota, gracias Aaron Mazel por notarlo. Pensé erróneamente que las rutas guardadas eran locales y se vaciarían automáticamente cuando el alcance se cerrara al final del entorno. En cambio, es global y se vacía al comienzo del próximo entorno tikzcd. La solución fue agregar la línea:
patchcmd[email protected]
globallet[email protected][email protected]
globallet[email protected][email protected]
globallet[email protected][email protected]
Un enfoque aquí sería romper la flecha que pasa por debajo en dos pedazos. Aquí hay algunas ideas sobre cómo hacer esto:
Una posibilidad es utilizar el hecho de que hay una celda de matriz exactamente en el punto donde desea que se rompa una de las flechas:
documentclassarticle
usepackagetikz-cd
begindocument
begintikzcd[]
& A arrowdd & \
B arrow[-]r & arrowrphi & C \
& D &
endtikzcd
enddocument
Alternativamente, puede utilizar el sistema de coordenadas perpendiculares de TikZ (consulte el manual pgf, sección 13.3.1). En el siguiente ejemplo, la flecha que comienza en B aterrizaría en D, pero modificamos la ruta real dibujada diciendo to path= tikztotarget)
(los to path
se explica en la sección 14.14 del manual pgf). Esto cambia el punto final de la flecha para que sea la intersección de una línea horizontal a través de tikztostart (en este caso, el nodo que contiene B) y una línea vertical a través de tikztotarget (en este caso, el nodo que contiene D). Para la segunda parte de esta flecha, procedemos de manera similar.
documentclassarticle
usepackagetikz-cd
begintikzcd[]
&
A arrowdd
& \
B arrow[-,
shorten >=0.7ex,
to path= tikztotarget)]
rd
&
&
C \
&
D arrow[shorten <=0.7ex,
to path=(tikztostart ]
ru
phi
&
endtikzcd
enddocument
Finalmente, se puede lograr una generalización de lo anterior para líneas posiblemente inclinadas o curvas utilizando el intersections
biblioteca (sección 13.3.2 del manual pgf). Espero que el siguiente ejemplo se explique por sí mismo.
documentclassarticle
usepackagetikz-cd
usetikzlibraryintersections
begintikzcd
A arrow[name path=above]rd
& B arrow[name path=below, draw=none]ld
arrow[name intersections=of=above and below,
-,
shorten >=0.7ex,
to path=-- (intersection-1)]
arrow[shorten <=0.7ex,
to path=(intersection-1) -- (tikztotarget) tikztonodes]
ldphi
\
C
& D
endtikzcd
enddocument
Si sostienes alguna incertidumbre y capacidad de modernizar nuestro crónica puedes escribir una explicación y con mucho gusto lo ojearemos.