考虑以下示例。
代码
% pdflatex -shell-escape test.tex
\documentclass{article}
\usepackage{auto-pst-pdf,pstricks-add}
\begin{document}
\psset{unit=0.08cm}
\begin{pspicture}(45,150)
\pspolygon(0,0)(1.147,8)(43.853,8)(45,0)
\pspolygon(2.147,8)(22.5,150)(42.853,8)
\pspolygon(3.147,8)(5.727,26)(39.273,26)(41.853,8)
\pspolygon(5.870,27)(8.450,45)(36.550,45)(39.130,27)
\pspolygon(8.593,46)(11.173,64)(33.827,64)(36.407,46)
\pspolygon(11.317,65)(13.897,83)(31.103,83)(33.683,65)
\pspolygon(14.040,84)(16.620,102)(28.38,102)(30.96,84)
\multido{\i=17+19}{5}{\pscircle(22.5,\i){1.5}}
\end{pspicture}
\end{document}
输出
问题
我确实有想要的输出,但坐标是使用以下抽屉标准手动计算的:
- 身高:150
- 宽度:45
- 底座高度:8
- 抽屉高度:18
- 两个连续抽屉之间的距离:1
我想在不手动计算坐标的情况下绘制它。我该怎么做?
答案1
\documentclass{article}
\usepackage{pstricks}\SpecialCoor
\begin{document}
\psset{unit=1mm}
\begin{pspicture}(-25,0)(25,150)
% Parameters
\def\h{150 } % height
\def\w{45 } % width
\def\hb{8 } % height of base
\def\hd{18 } % height of drawer
\def\d{1 } % vertical space between drawers
\def\b{1 } % horizontal space on either side of a drawer
\def\r{25 } % radius of handle
\def\N{7 } % number of drawers
\def\a{1 } % another parameter for the base
\def\c{2mm} % radius for the circle
% The following function returns the width of horizontal lines at a given height
\pstVerb{ /f { neg \h div 1 add \w mul \b dup add sub 0.5 mul } def
/hbh 0.5 1 \hb \h div add mul def }
\pspolygon(!\w 2 div neg 0)(!\w 2 div 0)(0,\h)
\psforeach{\iA}{1,2,..,\N}{%
\pstVerb{/z \iA\space 1 sub \d \hd add mul def }
\pspolygon(!z f neg z)(!z f z)(!z \hd add dup f exch)(!z \hd add dup f neg exch)
\pscircle(!0 .5 \hd mul \iA\space 1 sub \hd \d add mul add ){\c}
}
\pspolygon(!hbh neg \w mul \a sub \hb neg)%
(!hbh \w mul \a add \hb neg)%
(!.5 \w mul \a add 0)(!-.5 \w mul \a sub 0)
\end{pspicture}
\end{document}
答案2
这一次,这是 PSTricks 问题的 TikZ 解决方案:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[scale=.1,thick,line join=round]
% Parameters
\def\h{150} % height
\def\w{45} % width
\def\hb{8} % height of base
\def\hd{18} % height of drawer
\def\d{1} % vertical space between drawers
\def\b{1} % horizontal space on either side of a drawer
\def\r{1} % radius of handle
\def\N{7} % number of drawers
\def\a{1} % another parameter for the base
% The following function returns some relevant horizontal length
% (it takes a height as argument)
\pgfmathdeclarefunction{f}{1}{%
\pgfmathparse{.5*((1-#1/\h)*\w-2*\b)}%
}
% draw the chest
\draw ({-.5*\w},0) -- ({.5*\w},0) -- (0,\h) -- cycle;
% draw the base
\draw ({-.5*(1+\hb/\h)*\w-\a},-\hb)
--++({((1+\hb/\h)*\w+2*\a)},0)
--({.5*\w+\a},0)
--({-.5*\w-\a},0)
--cycle;
% draw the ... ahem .. drawers (incl. handles)
\foreach \i in {1,2,...,\N}{%
\def\z{\the\numexpr(\i-1)*(\d+\hd)}
\draw ({-f(\z)},\z)
--({f(\z)},\z)
--({f(\z+\hd)},{\z+\hd})
--({-f(\z+\hd)},{\z+\hd})
--cycle;
\draw (0,{.5*\hd+(\i-1)*(\hd+\d)}) circle (\r);
}
\end{tikzpicture}
\end{document}
答案3
\documentclass{article}
\usepackage[pdf]{pstricks}
\usepackage{pst-eucl}
\begin{document}
\psset{unit=0.08cm}
\newcommand\height{150 }% trailing spaces are necessary here!!
\newcommand\width{45 }
\newcommand\drawerheight{18 }
\newcommand\drawercount{5 }
\newcommand\baseheight{8 }
% The triangle of \height and \halfwidth has the angle a at the top (called point A).
% We calculate sin(a/2) and cos(a/2)
\edef\halfwidth{\width 2 div }
\edef\hypothenuse{\height \height mul \halfwidth \halfwidth mul add sqrt }
\edef\sinval{\halfwidth \hypothenuse div }
\edef\cosval{\height \hypothenuse div }
%#1 : distance from point A to bottom line of drawer
%#2 : height of trapezoid
%#3 : horizontal correction
\newcommand\trapezoid[3]{
\edef\ytop{#1 #2 sub }
\edef\ybottom{#1 }
\edef\hwtop{\ytop \cosval div \sinval mul #3 add }
\edef\hwbottom{\ybottom \cosval div \sinval mul #3 add }
\expandafter\pspolygon(!\hwtop -1 mul #2)(!\hwtop #2)
(!\hwbottom 0)(!\hwbottom -1 mul 0)
}
\newcommand\drawer[1]{%
\trapezoid{#1}{\drawerheight}{-1} \pscircle(0,9){1.5}
}
\begin{pspicture}(\width,\height)
% the base
\rput(! 0 0){\trapezoid{\height}{8}{1}}
% the cover
\edef\heightt{\number\numexpr\height - \baseheight}
\rput(! 0 \baseheight){\trapezoid{\heightt}{\heightt}{0}}
% the drawers
\edef\dhs{\number\numexpr\drawerheight+1}
\edef\start{\number\numexpr\height - (\drawercount-1)*\dhs - \baseheight}
\multido{\i=\start+\dhs}{\drawercount}{%
\rput(! 0 \height \i\space sub){\drawer{\i}}
}
\end{pspicture}
\end{document}
答案4
只是另一个解决方案!
\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-node}
\usepackage{multido}
\usepackage[nomessages]{fp}
% constants declarator
\def\LoadConstants{}
\newcommand\const[3][3]{%
\edef\temporary{trunc(#3}%
\expandafter\FPeval\csname#2\expandafter\endcsname
\expandafter{\temporary:#1)}%
\edef\LoadConstants{\LoadConstants
\noexpand\pstVerb{/#2 \csname#2\endcsname\space def}}%
\ignorespaces}
\psset{unit=1mm,linejoin=1}
\const{Width}{45}% Width
\const{Height}{150}% Height
\const{height}{18}% drawer height
\const{vgap}{1}% vertical gap between drawers
\const{hgap}{1}% horizontal gap for each drawer
\const{BaseWidth}{50}% base width
\const{BaseHeight}{5}% base height
\const{HalfWidth}{Width/2}
\const{Slope}{Height/HalfWidth}
\def\Drawer#1{%
\pnode(0,0){O}
\curvepnode{#1}{HalfWidth-hgap-t*height/Slope|t*height}{BR}
\pnode[!height vgap sub dup Slope div neg exch](BR){TR}
\nodexn{.5(O|TR)+.5(O|BR)}{C}
\pscircle(C){3pt}
\psline(O|BR)(BR)(TR)(O|TR)
}
\begin{document}
\const{HalfBaseWidth}{BaseWidth/2}
\begin{pspicture}(-\HalfBaseWidth,-\BaseHeight)(\HalfBaseWidth,\Height)
\LoadConstants
\multido{\i=0+1}{7}{\Drawer{\i}\psscalebox{-1 1}{\Drawer{\i}}}
\psline(-\HalfWidth,0)(0,\Height)(\HalfWidth,0)
\pspolygon(-\HalfBaseWidth,-\BaseHeight)
(!HalfBaseWidth neg BaseHeight Slope div add 0)
(!HalfBaseWidth BaseHeight Slope div sub 0)
(\HalfBaseWidth,-\BaseHeight)
\end{pspicture}
\end{document}