11

Consider the following example.

Code

% 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}

Output

enter image description here

Question

I do have the desired output but the coordiates are calculated manually using the following criteria for the chest of drawers:

  • Height: 150
  • Width: 45
  • Height of base: 8
  • Height of drawer: 18
  • Distance between two consecutive drawers: 1

I would like to draw it without having to calculate the coordiates manually. How do I do that?

  • There seems to be a lot of unnecessary hard-coding in your MWE. Surely, a loop could be used to draw the drawers too. Unfortunately, I don't know how to use PSTriks (yet!), so I can't advise you. – jub0bs Apr 21 '13 at 20:08
  • @Jubobs Indeed. That's what I'm saying in the question, too. :) – Svend Tveskæg Apr 21 '13 at 20:14
10
\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}
  • I copied it only from the other answer. I also modified the coordinates for pspicture – user2478 Apr 22 '13 at 5:52
  • a trailing space after \pstVerb is dangerous. – kiss my armpit Apr 22 '13 at 13:19
  • @Bugbusters: No! Not in this case! – user2478 Apr 22 '13 at 13:41
  • Making every PSTricks object able to accept node expression might be useful. For example: \pnode(2,2){A}\pscircle(.5(A|0,0)-.25(1,2|A)){2pt}. – kiss my armpit Apr 23 '13 at 17:25
8

For once, here is a TikZ solution to a PSTricks question:

enter image description here

\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}
6
\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}
2

Just another solution!

enter image description here

\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}

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.