在 TikZ 中绘制声学场景(头部和扬声器)

在 TikZ 中绘制声学场景(头部和扬声器)

我对在 Tikz 中绘制声学和音频研究中非常常见的图形场景很感兴趣。本质上,它由中心的草图头部和头部周围不同角度的一个或多个扬声器组成。

大致如下(我只说想法,不说具体细节):

在此处输入图片描述

我设法完成了一些事情,但我对结果不太满意,原因有二:

  1. 我无法选择minimum height梯形顶部的矩形,因此必须使用scale使其变薄

  2. 我不喜欢在旋转之后必须手动调整矩形的 x 和 y 偏移。

有没有简单的方法可以参数化整个扬声器符号的旋转?

提前致谢!这是 MWE(出于某种原因,我无法将图像外部化为 PNG :/)

\documentclass{article}
\usepackage[mode=buildnew]{standalone}% requires -shell-escape

\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\pgfplotsset{plot coordinates/math parser=false}
\usepackage{tikz}                       %inline graphics
\usetikzlibrary{plotmarks,dsp,chains,calc,shapes.geometric}
\usetikzlibrary{hobby,backgrounds,trees,snakes,shapes.callouts,positioning,pgfplots.groupplots}


\begin{document}

    %
    \begin{tikzpicture}[anchor=center,remember picture,overlay]
        %\*
        % Head
        \node[thick,circle,minimum size=1.25cm,draw] at (0,0)
          (head) {};
        \draw [thick,] ([xshift=-3pt,yshift=-0.9pt]head.north) -- ([yshift=5pt]head.north) -- ([xshift=3pt,yshift=-0.9pt]head.north);
        % Circle
        \node[thick,dashed,circle,minimum size=3.0cm,draw] at (0,0)
          (ah) {};      
        % LS at 0deg
        \node[draw,thick,fill=gray,trapezium,minimum width=10pt,shape border rotate=0,shape border uses incircle] at ($(ah)+(90:1.5cm)$)  (ls1) {};
        \node[scale=0.75,draw,thick,fill=gray,minimum width=14pt] at ($(ls1.north)+(0,1.5pt)$)  (ls12) {};
        % LS at 40deg
        \node[draw,thick,fill=gray,trapezium,shape border rotate=-40,shape border uses incircle] at ($(ah)+(50:1.5cm)$) (ls2) {};
        \node[scale=0.75,draw,thick,fill=gray,minimum width=14pt,rotate=-40] at ($(ls2.north)+(5pt,-0.75pt)$)  (ls22) {};
        %*/
    \end{tikzpicture}%
    %    

答案1

我会用pics 来表示说话者和人体头部:

在此处输入图片描述

代码:

\documentclass[border=5pt]{standalone}
\usepackage{tikz}

\definecolor{skin}{RGB}{248,198,135}
\definecolor{mygreen}{RGB}{66,213,0}

\newcounter{speaker}

\tikzset{
  Speaker/.pic={
    \filldraw[fill=gray!40,pic actions] 
    (-15pt,0) -- 
      coordinate[midway] (-front) 
    (15pt,0) -- 
    ++([shift={(-6pt,8pt)}]0pt,0pt) coordinate (aux1) -- 
    ++(-18pt,0) coordinate (aux2) 
    -- cycle 
    (aux1) -- ++(0,6pt) -- coordinate[midway] (-back) ++(-18pt,0) -- (aux2);
  },
  Human/.pic={
    \filldraw[fill=mygreen] 
      (0,0.7cm) ellipse [x radius=10pt,y radius=5pt]
      (0,-0.7cm) ellipse [x radius=10pt,y radius=5pt];    
    \filldraw[fill=skin] 
      (0.7,4pt) -- (0.7,-4pt) -- (0.95,0pt) -- cycle;    
    \filldraw[fill=skin] 
      (0,0) ellipse [x radius=0.8cm, y radius=0.7cm];
    \filldraw[fill=brown!85!black] 
      (0.5,0.55) arc[start angle=50,end angle=310,x radius=0.8cm, y radius=0.7cm]
      to[out=60,in=230] cycle;
    \filldraw[fill=mygreen,rounded corners]
      (-0.2,0.75) -- (0.2,0.75) -- (0.2,-0.75) -- (-0.2,-0.75) -- cycle;  
  }
}

\begin{document}

\begin{tikzpicture}
\foreach \Radius/\Shade in {4.2/10,4.1/20,4/40,3.9/60,3.8/80}
\fill[mygreen!\Shade]
  (0,0) circle [radius=\Radius];
\fill[white]
  (0,0) circle (3cm);
\foreach \Angle [count=\xi] in {0,30,60,140,280}
  \pic[rotate=\Angle-90] (sp\xi) at (\Angle:3cm) {Speaker};
\draw[dashed]
  (210:4.2cm) -- (30:4.2cm)
  (120:4.2cm) -- (300:4.2cm);
\pic[rotate=30] {Human};
% draw some arrows from and to the speakers
\draw[-latex] (sp1-front) -- ++(-10pt,0pt);
\draw[-latex] (sp1-back) -- ++(10pt,0pt);
\draw[latex-] (sp3-front) -- ++(240:10pt);
\draw[latex-] (sp3-back) -- ++(60:10pt);
\end{tikzpicture}

\end{document}

答案2

只是另一种方式...

\documentclass[tikz,border=5]{standalone}
\tikzset{%
human/.style={draw=brown!50!black, fill=pink!50!brown},
hair/.style={draw=brown!25!black, fill=brown!50!black},
headphone/.style={draw=olive!50!black, fill=green!50!black!50!yellow},
directions/.style={draw=gray, dashed},
source/.style={draw=gray!50!black, fill=gray!50},
acoustic field/.style={fill=blue!50!cyan!50},
azimuth/.store in=\azimuth, azimuth/.default=0,
distance/.store in=\distance, distance/.default=0,
pics/.cd,
listener/.style={code={
  \tikzset{#1, rotate=90-\azimuth}
  \path [directions] (0:2) -- (180:2) (90:2) -- (270:2);
  \path [headphone] (90:1/4 and 4/22) circle [radius=1/8];
  \path [headphone] (-90:1/4 and 4/22) circle [radius=1/8];
  \path [human]
    (0:1/4) ellipse [x radius=2/22, y radius=1/22];
  \path [human]
    (0:0) ellipse [x radius=1/4, y radius=5/22-1/64]; 
  \path [hair]
    (60:1/4 and 5/22) arc (60:300:1/4 and 5/22)
    .. controls ++(45:1/8) and ++(225:1/8) .. cycle;
  \path [headphone] (255:1/4) rectangle (75:1/4);
}},
source/.style={code={
  \tikzset{#1, rotate=90-\azimuth, shift=(0:\distance)}
  \path [source] (0,1/8) 
   -- (1/12,1/8) arc (90:270:-1/32 and 1/8) 
   -- (0,-1/8) -- (-1/8,-1/8-1/8)
    arc (270:90:1/16 and 1/4) -- (0,1/8)   --cycle;
  \path [source, fill=none] (0,1/8) arc (90:270:1/32 and 1/8);
}}}
\begin{document}
\begin{tikzpicture}[line cap=round, line join=round]
\fill [acoustic field, even odd rule] 
  circle [radius=27/16]  circle [radius=10/8];
\pic {listener={azimuth=60}};
\foreach \a in {90, 60, 30, -60, -210}
  \pic {source={azimuth=\a, distance=3/2}};
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案3

使用 PSTricks 的解决方案。头部形状和头发太过琐碎,不值得考虑,因此我保留它们,不提供任何保修。

\documentclass[pstricks]{standalone}

\psset{unit=1mm,runit=\psunit,dimen=m}

\def\sp{
    \pspolygon(-10,0)(10,0)(5,5)(-5,5)
    \psframe(-5,5)(5,8)
}

\def\hd{{
    \psset{fillstyle=solid,fillcolor=green} 
    \pscircle(-10,0){4}
    \pscircle(10,0){4}
    \pscircle[fillcolor=brown]{10}
    \pspolygon[fillcolor=brown](10;80)(13;90)(10;100)
    \psframe[framearc=.2](-11,-3)(11,3)
}}

\begin{document}
\begin{pspicture}(-90,-90)(90,90)
    \foreach \x in {80,78,...,50}{\pscircle*[linecolor=green!\the\numexpr80-\x]{\x}}
    \pscircle*[linecolor=white]{40}
    \rput{-45}(0,0){\hd}
    \foreach \x in {-45,45,135,225}{\psline[linestyle=dashed](90;\x)}
    \foreach \x in {10,45,80,150,300}{\rput{!\x\space 90 sub}(50;\x){\sp}}
\end{pspicture}
\end{document}

在此处输入图片描述

相关内容