4

I am trying to label curves which are created by the package hobby. However, I can not align labels properly in the horizontal and vertical direction.

In the first image I am able to use specific coordinates to align at least horizontally. However, the vertical alignment fails.

In the second tikzpicture I try to label the curves without using specific coordinates, but rather with nodes. Failing once again.

Thank you for any help.

\documentclass[tikz]{standalone}
\usetikzlibrary{hobby}

\begin{document}

 \begin{tikzpicture}[thick] 

    % A
    \node[orange] (A) at (11,4.58) {A} ; 
    \draw[orange] (5,4.58) -- (A); 
    \draw[orange] (-4,7) to[closed,curve through={(-3,-4.58) .. (0,-3) .. (5,4.58)}] (4,7) ;
 
    % B 
    \node[red]  (B) at (11,0.72) {B} ;
    \draw[red] (2.0,0.72) -- (B); 
    \draw[red] (-1,6) to[closed,curve through={(-2,0.72) .. (0,-1) .. (2,0.72)}] (1,6) ;

    % C
    \node[green]  (C) at (11,2) {C} ;
    \path (0,2) node[circle,draw,green,minimum size = 1cm](circle) {} ;
    \draw[green] (circle) -- (C);   
  
 \end{tikzpicture}



 \begin{tikzpicture}[thick] 

    % A
    \node[orange] (A) at (11,4.58) {A} ; 
   \draw[orange] (-4,7) to[closed,curve through={(-3,-4.58) .. (0,-3) .. (5,4.58)}] (4,7) node(a) {} ;
    \draw[orange] (a) -- (A); 
 
    % B 
    \node[red] (B) at (11,0.72) {B} ;
    \draw[red] (-1,6) to[closed,curve through={(-2,0.72) .. (0,-1) .. (2,0.72)}] (1,6) node(b) {};
    \draw[red] (b) -- (B);

    % C
    \node[green] (C) at (11,2) {C} ;
    \path (0,2) node[circle,draw,green,minimum size = 1cm](circle) {} ;
    \draw[green] (circle) -- (C);   
  
 \end{tikzpicture}

\end{document}

First tikzpicture

Second tikzpicture

4
  • It remains not clear to me. What is the wanted output? What vertical alignment is missed in the first picture?
    – SebGlav
    Commented Jun 18, 2022 at 13:55
  • Thank you. I am sorry for not being clear. The horizontal alignment is fine (the labels start at the same spot at the right side) in the first tikzpicture. But the vertical alignment should be like that every label has the same vertical distance to the next label.
    – 17757970
    Commented Jun 18, 2022 at 14:01
  • And do you car about lines to remain horizontal or not?
    – SebGlav
    Commented Jun 18, 2022 at 14:05
  • Yes, the lines to the labels should be horizontal.
    – 17757970
    Commented Jun 18, 2022 at 14:05

2 Answers 2

5

It feels as though you are trying to treat a curve as the boundary of a node. Since your circle path actually is the boundary of a node then it comes with a whole slew of information, in the form of anchors, that can be used to connect it to other things. Normal paths don't have that facility and can't be given them. Your second code places nodes at various locations on the curves and then connects them to the labels. Since you don't specify where those nodes should be on the curves, there's no reason for the connecting lines to be horizontal.

If you want to place the labels at specific places and then connect them to the curves via horizontal lines, then the simplest way to do that is to use the intersections library. In the following code, each curve is drawn and named, each label is placed at a suitable location, and then a horizontal path is defined (but not drawn) so that the correct location for the label line can be found. Using the intersections library, the places where that line connects with the curve are found and then these can be used to draw the label line.

Note that there's nothing special about the fact that the curves are defined using the hobby library here. The same would occur with any path construction.

\documentclass{article}
%\url{https://tex.stackexchange.com/q/648162/86}
\usepackage{tikz}
\usetikzlibrary{hobby,intersections}

\begin{document}

 \begin{tikzpicture}[thick,scale=.3] 

    % A
\node[orange] (A) at (11,5) {A};
\draw[orange,name path=A] (-4,7) to[closed,curve through={(-3,-4.58) .. (0,-3) .. (5,4.58)}] (4,7) ;
\path[name path=AA,overlay] (A) -- +(-20,0);
\draw[name intersections={of=A and AA},orange] (intersection-2) -- (A);
 
    % B 
\node[red]  (B) at (11,0) {B} ;
\draw[red,name path=B] (-1,6) to[closed,curve through={(-2,0.72) .. (0,-1) .. (2,0.72)}] (1,6) ;
\path[name path=BB,overlay] (B) -- +(-20,0);
\draw[name intersections={of=B and BB},orange] (intersection-2) -- (B);

    % C
\node[green]  (C) at (11,2.5) {C} ;
\draw[green,name path=C] (0,2) circle[radius=1cm];
\path[name path=CC,overlay] (C) -- +(-20,0);
\draw[name intersections={of=C and CC},green] (intersection-1) -- (C);
  
 \end{tikzpicture}
\end{document}

(I scaled the image down so that it would fit with the article class; that can obviously be removed.)

Result:

Paths with connecting lines to labels

7
  • 2
    This is exactly what I should have done in the first place. I thought that hobby curves were not easy to be used with the intersections library and even didn't try. I was wrong. +1
    – SebGlav
    Commented Jun 18, 2022 at 18:04
  • 2
    @SebGlav A hobby curve is ultimately just a series of bézier curves so once it's been constructed then it can be used just as any path can be. Commented Jun 18, 2022 at 20:03
  • 2
    You're right, but I failed at placing coordinates on it like I usually do on other curves, adding coordinate[pos=0.75](c) for example. I assumed incorrectly from this issue.
    – SebGlav
    Commented Jun 18, 2022 at 20:06
  • 2
    @SebGlav Ah, I see what you're working with there. A hobby curve generally produces multiple bézier curves so with the curve through construction then it's not obvious how to determine where to put the nodes. However, with use Hobby shortcut then it works as it should. Try \draw[use Hobby shortcut] (0,0) .. node {a} (1,1) .. node {b} (2,0) .. node {c} (3,1) .. node {d} (4,0); to see what I mean. Commented Jun 18, 2022 at 20:11
  • 2
    Thanks a lot, that's exactly what I was struggling with.
    – SebGlav
    Commented Jun 18, 2022 at 20:16
4

This is a version without any fancy intersection calculation (since it's not easy to do with hobby curves).

hobby with labels

\documentclass[tikz]{standalone}
\usetikzlibrary{hobby,positioning}

\begin{document}

    \begin{tikzpicture}[thick] 
        
        % A
       \draw[orange] (-4,7)  to[closed,curve through={(-3,-4.58) .. (0,-3) .. (5,4.58)}]  (4,7) coordinate(a);
     
        % B 
        \draw[red] (-1,6) to[closed,curve through={(-2,0.72) .. (0,-1) .. (2,0.72)}] (1,6) coordinate (b);
    
        % C
        \path (0,2) node[circle,draw,green,minimum size = 1cm](circle) {} ;
        
        % Labels
        \newcommand{\dist}{8}
        \draw[green] (circle) --++ (\dist,0) node[right] (c) {C}; 
        \node[above = 2cm of c,red] (b) {B};
        \node[above = 2cm of b,orange] (a) {A};
        \draw[red] (b) --++ (-\dist+2.08,0);
        \draw[orange] (a) --++ (-\dist+3.74,0);
         
    \end{tikzpicture}

\end{document}
2
  • Thank you once again. I am little bit confused as I try to replicate your method. Does "without any fancy intersection calculation" means that you find out the coordinates of the intersection from the curve and the line to the label manually? Or why did you choose "8" as corner stone of your code?
    – 17757970
    Commented Jun 18, 2022 at 14:59
  • 2
    I chose 8 as the distance from the green circle and the node C. Then manually determined the other distances. That was what without any fancy calculation meant. Actually, Andrew Stacey's answer is the more elaborated one, using intersections library, which finally worked well with the hobby path (as opposite to what I thought initially).
    – SebGlav
    Commented Jun 18, 2022 at 18:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .