2

My question is:

  • Is it possible to align any two nodes by aligning their subnodes?

  • For TikZ nodes, is it possible to add a new anchor to an existed nodes?
    (for example: add node-b.north as an new anchor of node-a)

In this example, I try to put the "Delta" of 2 nodes on a same vertical line, but I failed.

\documentclass[10pt,a4paper, utf-8]{article}
\usepackage{
    amsmath, 
    mathtools,
    amsfonts,
    amssymb,
    tikz
}
\usetikzlibrary{
    tikzmark,
    positioning,
    matrix,
}

\begin{document} \begin{tikzpicture}[remember picture] \node(a) [draw] {$A \subnode[draw]{sub-a}{\Delta} B \wedge C$}; \node(b) [draw,anchor=sub-b,below=1pt of sub-a]{$A \wedge C \subnode{sub-b}{\Delta} B$}; \end{tikzpicture} \end{document}

My idea is to drop the anchor of b from sub-b to sub-a (like matrix: you can set matrix anchor=inner node).
I use tikzmark to obtain two "Delta"s' coordinates.
When I try to set the starting point of anchor, it doesn't work.

An simple analogy may help you understand my idea:
if node b is a ship, then
command "anchor=..." set the release point of the anchor,
command "below=..." set the destination of the anchor.


PS:

Although matrix is a possible solution,
but it's troublesome when the "Delta" was inside a fraction(for example, the "Delta" is inside the denominator) .
The code block shown above is just an simple example,
what I really hope to see is a more general solution(stated in the title).

The first question has been answered, but I really like to see the answer of the second question(For TikZ nodes, is it possible to add a new anchor to an existed nodes?).

And please, do not delete your original answer. They are also useful ^__^.

  • Welcome to TeX. SE! – Zarko Oct 16 '20 at 13:30
  • ^__^ Thank you! – ZIYAN CHEN Oct 16 '20 at 14:03
  • See https://tex.stackexchange.com/questions/491915/ , its look like that your question is duplicate to it. – Zarko Oct 16 '20 at 15:39
  • 1
    Not sure I understand your second point correctly, but when you do below=of foo, that will automatically set anchor=north. Hence, if you want to use a different anchor, the anchor setting has to come after the positioning setting, e.g. below=of foo, anchor=north east. However, it doesn't look like you can use sub-b as an anchor in your example. – Torbjørn T. Oct 16 '20 at 16:56
  • OK thanks. I think the anchor must be like "s.mid", "s.base", etc. Seems like it's impossible to choose a random point as the anchor of the node. I just read the question Add more anchors to standard TikZ nodes, maybe we should add the anchors manually? >__< – ZIYAN CHEN Oct 16 '20 at 17:10
  • @Zarko I disagree with the duplicate. This is positioning within a single tikzpicture whereas that one annotates a non-tikz element with tikz drawings. – Andrew Stacey Oct 16 '20 at 19:21
  • I've no idea who down-voted this or why, but I think it's a very subtle question and clear what is being asked so I think it deserves a few up-votes. – Andrew Stacey Oct 16 '20 at 20:09
  • @AndrewStacey, of course you can disagree with me. But, regarding to OP comment to my deleted answer, the question is not clear to me and need some more details. Anyway, as I see, there are two solution which gives similar result for particular case given in OP question, which I provide in my now deleted answer and which OP didn't like (so I delete it). – Zarko Oct 16 '20 at 21:16
  • @Zarko Quite often alignment issues in a tikzpicture are best solved by using a matrix so I think your (deleted) answer (which I can see) was a good one. The criterion of using subnodes introduces some subtleties due to when and how coordinates are determined which makes this particular situation more complex. I just felt that the suggested duplicate wasn't close enough and so wanted to avoid it getting closed. – Andrew Stacey Oct 16 '20 at 21:47
  • @AndrewStacey, i suggest to be closed not because it is duplicate but that it need clarification, what is the real problem. By this I like to encourage OP, that gives more explanation and maybe some sketch, what it is the problem. The way, how it present in MWE, is (as have been teach in EE a long time ago) bootstrap problem. However, with given link I guessing, that maybe use of tikzmark nodes on showed way is close enough for show a way how to solve OP's problem. Apparently I'm wrong. – Zarko Oct 16 '20 at 21:56
  • @Zarko My apologies - I've misunderstood the chain of events. I saw the vote-to-close and the comment about the duplicate and assumed that the reason for the vote-to-close was that you thought it was a duplicate question of the one you linked to. Possibly had you not used the word "duplicate" then I wouldn't have made that assumption! But that word has special meaning on the SE network so may I suggest that if you're recommending that someone look at another question to see if it is relevant then you don't use that word. – Andrew Stacey Oct 16 '20 at 22:03
  • I think your second question is not yet clear. To add new anchors, as in Martin's code that you link in a comment, then there needs to be a way to algorithmically determine where they are. So where do you want these anchors to be? If it depends on a subnode then that can't be done in the same way as normal node anchors due to how subnodes are created. So the calc syntax is probably the best strategy here. – Andrew Stacey Oct 17 '20 at 20:52
  • You are right...I will accept your answer. Really appreciate your help. – ZIYAN CHEN Oct 18 '20 at 02:53

2 Answers2

3

This solution uses scopes, first to compute the relative position of (sub-b) and (b), then to shift them where they are needed. Due to [remember picture], I could not reuse node names (b) and (sub-b). Note that (b.center) and (c.center) are at the origins of their respective scopes.

\documentclass{standalone}
\usepackage{
    amsmath, 
    mathtools,
    amsfonts,
    amssymb,
    tikz
}
\usetikzlibrary{
    tikzmark,
    positioning,
    matrix,
    calc
}

\begin{document} \begin{tikzpicture}[remember picture] \node(a) [draw] {$A \subnode[draw]{sub-a}{\Delta} B \wedge C$}; \begin{scope}[opacity=0] \node(b) [draw]{$A \wedge C \subnode{sub-b}{\Delta} B$}; \coordinate(S) at ($(sub-a.south)-(sub-b.north)-(0,1pt)$); \end{scope} \begin{scope}[shift=(S)] \node(c) [draw]{$A \wedge C \subnode{sub-c}{\Delta} B$}; \end{scope} \end{tikzpicture} \end{document}

demo

John Kormylo
  • 79,712
  • 3
  • 50
  • 120
3

This is a subtle one! On the face of it, it seems straightforward. We cannot directly use the \subnode coordinate in positioning the outer node (b) because its location on the page is not known until after node b is placed. But there is a standard way around this - we save the various necessary locations to the aux file and load them in before positioning the nodes.

If it were this simple, what we would do is save the locations of the sub-b node and the b node and then use their difference to adjust the position of the b node. Although this moves b, it also moves sub-b by the same amount so their difference remains the same.

The snag is that the coordinates of the subnode (sub-b) are already based on the previous compilation. So the above strategy doesn't work because TikZ always thinks that sub-b is located where it was on the previous compilation. But the position of the b node is based on the current compilation. So TikZ is continually playing a game of chase as node b chases the sub-b subnode around the page.

To get out of this trap, we need to also use the position of b on the previous compilation. Fortunately, tikzmark can handle the saving part. A consequence of this is that this requires three compilations to settle.

\documentclass[10pt,a4paper]{article}
%\url{https://tex.stackexchange.com/q/567070/86}
\usepackage{
    amsmath, 
    mathtools,
    amsfonts,
    amssymb,
    tikz
}
\usetikzlibrary{
    tikzmark,
    calc,
}

\begin{document} \begin{tikzpicture}[remember picture] \node(a) [draw] {$A \subnode{sub-a}{\Delta} B \wedge C$}; \node(b) [draw] at ($(sub-a.south)-(pic cs:b)$) {$A \wedge C \subnode{sub-b}{\Delta} B$}; \begin{scope}[overlay] \tikzmark{a}{(b.center)} \tikzmark{b}{($(sub-b.north)-(pic cs:a)$)} \end{scope} \end{tikzpicture} \end{document}

Subnodes aligned

Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751
  • Thank you! This is close to what I want. I'm reading the source code of \subnode of tikzmark. Although this answer is perfect, I would like to see more examples. – ZIYAN CHEN Oct 17 '20 at 03:24
  • @ZIYANCHEN I'll need a bit more guidance of what examples would be useful. Using subnodes for positioning their parent node is not something I'd considered before so I don't know what examples would be illustrative or useful. Is there something specific that you are trying to do which is tricky to adapt my answer to? If so, do edit your question to make that clear. – Andrew Stacey Oct 17 '20 at 08:05
  • OK give me some time to think...I will reorganize the question. Sorry for my lack of vocabulary. – ZIYAN CHEN Oct 17 '20 at 14:04
  • I just updated my question. If you need more information, do not hesitate to ask me :) – ZIYAN CHEN Oct 17 '20 at 16:44