5

I have a pic element draw headphone, it works perfect but node distance is measured from center but not border as other nodes.

\documentclass[border=2pt,convert={outfile=\jobname.png}]{standalone}
\usepackage{tikz} 
\usetikzlibrary{calc,positioning}
\begin{document}
  \begin{tikzpicture}[node distance=1cm and 1cm,
    box/.style = {draw, circle,minimum size=1cm,inner sep=4pt},
       headphone/.pic={
        \node[circle,fill={rgb,255 :red,220; green,150; blue,100},inner sep=0,anchor=center] (-outline) at (0,0) {};
        \begin{scope}[x={(-outline.east)},y={(-outline.north)},scale=2]
          \fill[white,rounded corners=1pt] ($(-40:.3)+(0,-0.2)$) -- ($(-40:.3)+(-0.15,-0.2)$) -- ($(-40:.3) + (-0.15,0)$) -- 
          (-40:.3) arc [start angle=-40,end angle=220, radius=0.3] --
          ++ (0.15,0) --++(0,-0.2) -- ++(-0.15,0) --
          (225:.35) arc [start angle=225,end angle=-45, radius=0.35] --cycle;
          \draw[draw={rgb,255 :red,220; green,150; blue,100}] (-40:.325) arc [start angle=-40,end angle=220, radius=0.325];
        \end{scope}}
    ]
    \draw[help lines] (-1,-3) grid (3,1);
    \node[box] (A) {A};
    \node[box,right=of A] (B) {B};
    \node[box,below=of B] (C) {C};
    \pic[left=1cm of C,minimum size=1cm] (D) {headphone};
  \end{tikzpicture}
\end{document}

enter image description here

It caused by the anchor=center parameter in -outline box, but if I remove that, the coordinate within the scope will not work.

1
  • 1
    In this case I would just do \pic[minimum size=1cm] (D) at (A |- C) {headphone}; I think. Nov 16, 2017 at 22:58

3 Answers 3

3

If you were to write \node[anchor=east] (-outline) at (0,0) {}; it would put (-outline.east) at (0,0), which in this case puts the center of the node at (-.5,0) in the pic coordinates. Since the origin of your pic is not at (-outline.center), your vector arithmetic is off. You can fix it by shifting the scope to the correct origin before you scale it:

\begin{scope}[shift=(-outline),x={(-outline.east)},y={(-outline.north)},scale=2]

(and of course remove anchor=center).

[I also ought to point out that while you have gone to pains to make the headphones scale with the node, the rounded corners parameter does not scale. It actually seems pretty tricky to get it to do so.]

4
  • You are right, it works. any suggestion for rounded corner not work for scale issue?
    – beetlej
    Nov 17, 2017 at 3:42
  • I haven't seen any good way of getting rounded corners to scale. Most other ways of drawing curves will scale, though. See this answer for some options.
    – Emma
    Nov 17, 2017 at 4:34
  • Alternatively, Torbjørn T.'s solution will also scale correctly, since it's importing the compiled picture rather than rendering it again at at different size.
    – Emma
    Nov 17, 2017 at 5:10
  • Yes, use to [out=xx,in=xx] will help improve. Thanks
    – beetlej
    Nov 17, 2017 at 16:20
5

In this case I would simply do

\pic[minimum size=1cm] (D) at (A |- C) {headphone};

avoiding the use of the positioning library altogether.

I could suggest a completely different approach to this though. First, make a new file headphone.tex, containing only the headphone symbol, however you like to draw it, e.g.

\documentclass{standalone}
\usepackage{tikz} 
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[
       headphone/.pic={
        \node[circle,fill={rgb,255 :red,220; green,150; blue,100},inner sep=0,anchor=center] (-outline) at (0,0) {};
        \begin{scope}[x={(-outline.east)},y={(-outline.north)},scale=2]
          \fill[white,rounded corners=1pt] ($(-40:.3)+(0,-0.2)$) -- ($(-40:.3)+(-0.15,-0.2)$) -- ($(-40:.3) + (-0.15,0)$) -- 
          (-40:.3) arc [start angle=-40,end angle=220, radius=0.3] --
          ++ (0.15,0) --++(0,-0.2) -- ++(-0.15,0) --
          (225:.35) arc [start angle=225,end angle=-45, radius=0.35] --cycle;
          \draw[draw={rgb,255 :red,220; green,150; blue,100}] (-40:.325) arc [start angle=-40,end angle=220, radius=0.325];
        \end{scope}}
    ]
    \pic[minimum size=1cm] (D) {headphone};
\end{tikzpicture}
\end{document}

You can then use a path picture to put this image on the background of a circular node, as follows:

\documentclass[border=2pt]{standalone}
\usepackage{tikz} 
\usetikzlibrary{calc,positioning}
\begin{document}
\begin{tikzpicture}[node distance=1cm and 1cm,
    box/.style = {draw, circle,minimum size=1cm,inner sep=4pt},
    headphone/.style={
       circle,minimum size=#1,
       path picture={\node [anchor=center] at (path picture bounding box.center) {\includegraphics[width=#1]{headphone}};}
    },
    headphone/.default=1cm
    ]
    \draw[help lines] (-1,-3) grid (3,1);
    \node[box] (A) {A};
    \node[box,right=of A] (B) {B};
    \node[box,below=of B] (C) {C};
    \node[headphone,left=1cm of C] (D) {};

\end{tikzpicture}
\end{document}

output of last code block

1
  • Thanks, never know path picture usage before! great idea.emma's suggestion works for my case also.
    – beetlej
    Nov 17, 2017 at 3:43
2

A little bit tweak Torbjørn T.'s answer,path picture is awesome for this case w/o new tex file:

\documentclass[border=2pt,convert={outfile=\jobname.png}]{standalone}
\usepackage{tikz} 
\usetikzlibrary{calc,positioning}
\begin{document}
  \begin{tikzpicture}[node distance=1cm and 1cm,
    box/.style = {draw, circle,minimum size=1cm,inner sep=4pt},
   headphone/.style = {path picture={
       \node[circle,fill={rgb,255 :red,220; green,150; blue,100},anchor=center] (-outline) {};
       \begin{scope}[x={(-outline.east)},y={(-outline.north)}]
             \fill[white] (-50:.5) arc [start angle=-50,end angle=230, radius=.5] to[out=45,in=135] ++(0.2,0) to[out=-45,in=45] ++(0,-0.2) to[out=-135,in=-45] ++(-0.2,0) to[out=135,in=-90] (230:.55) arc [start angle=230,end angle=-50, radius=.55] to[out=-90,in=45] ($(-50:.5)+(0,-.2)$) to[out=-135,in=-45] ($(-50:.5)+(-.2,-.2)$) to[out=135,in=-135] ($(-50:.5)+(-.2,0)$) to[out=45,in=135] cycle; 
       \end{scope}
                }}
    ]
    \draw[help lines] (-1,-3) grid (3,1);
    \node[box] (A) {A};
    \node[box,right=of A] (B) {B};
    \node[box,below=of B] (C) {C};
    \node[left=1cm of C,minimum size=1cm,headphone] (D) {};
  \end{tikzpicture}
\end{document}

Output:

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.