我对在 Tikz 中绘制声学和音频研究中非常常见的图形场景很感兴趣。本质上,它由中心的草图头部和头部周围不同角度的一个或多个扬声器组成。
大致如下(我只说想法,不说具体细节):
我设法完成了一些事情,但我对结果不太满意,原因有二:
我无法选择
minimum height
梯形顶部的矩形,因此必须使用scale
使其变薄我不喜欢在旋转之后必须手动调整矩形的 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
我会用pic
s 来表示说话者和人体头部:
代码:
\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}