% \iffalse meta-comment, etc. %% %% Package `pst-3d.dtx' %% %% Timothy Van Zandt (tvz) %% Herbert Voss (hv) %% %% September 03, 2005 %% %% This file is under the LaTeX Project Public License %% See CTAN archives in directory macros/latex/base/lppl.txt. %% %% DESCRIPTION: %% `pst-3d' is a PSTricks package for tilting and other pseudo-3D tricks %% % \fi % \iffalse %<*driver> \documentclass{ltxdoc} \GetFileInfo{pst-3d.dtx} \usepackage[T1]{fontenc} \usepackage{textcomp,fancyvrb} \usepackage{graphics,showexpl} \usepackage{amsmath,array} \usepackage{multido} \usepackage{pstricks,pst-node,pst-plot} \usepackage{pst-3d} \AtBeginDocument{ % \OnlyDescription % comment out for implementation details \EnableCrossrefs \RecordChanges \CodelineIndex} \AtEndDocument{ \PrintChanges \PrintIndex} \hbadness=7000 % Over and under full box warnings \hfuzz=3pt \begin{document} \DocInput{pst-3d.dtx} \end{document} % % \fi % % \changes{v1.00}{2005/09/08}{% % using the extended pst-xkey instead of the old pst-key package; % creating a dtx file; % new \LaTeX\ wrapper file (hv)} % \changes{v0.90}{2001/02/16}{First public release. (tvz)} % % \DoNotIndex{\!,\",\#,\$,\%,\&,\',\(,\+,\*,\,,\-,\.,\/,\:,\;,\<,\=,\>,\?} % \DoNotIndex{\@,\@B,\@K,\@cTq,\@f,\@fPl,\@ifnextchar,\@nameuse,\@oVk} % \DoNotIndex{\[,\\,\],\^,\_,\ } % \DoNotIndex{\^,\\^,\\\^,$\^$,$\\^$,$\\^$} % \DoNotIndex{\0,\2,\4,\5,\6,\7,\8,} % \DoNotIndex{\A,\a} % \DoNotIndex{\B,\b,\Bc,\begin,\Bq,\Bqc} % \DoNotIndex{\C,\c,\catcode,\cJA,\CodelineIndex,\csname} % \DoNotIndex{\D,\def,\define@key,\Df,\divide,\DocInput,\documentclass,\pst@addfams} % \DoNotIndex{\eCN,\edef,\else,\eHd,\eMcj,\EnableCrossrefs,\end,\endcsname} % \DoNotIndex{\endCenterExample,\endExample,\endinput,\endpsclip} % \DoNotIndex{\PrintIndex,\PrintChanges,\ProvidesFile} % \DoNotIndex{\endpspicture,\endSideBySideExample,\Example} % \DoNotIndex{\F,\f,\FdUrr,\fi,\filedate,\fileversion,\FV@Environment} % \DoNotIndex{\FV@UseKeyValues,\FV@XRightMargin,\FVB@Example,\fvset} % \DoNotIndex{\G,\g,\GetFileInfo,\gr,\GradientLoaded,\gsFKrbK@o,\gsj,\gsOX} % \DoNotIndex{\hbadness,\hfuzz,\HLEmphasize,\HLMacro,\HLMacro@i} % \DoNotIndex{\HLReverse,\HLReverse@i,\hqcu,\HqY} % \DoNotIndex{\I,\i,\ifx,\input,\Ir,\IU} % \DoNotIndex{\j,\jl,\JT,\JVodH} % \DoNotIndex{\K,\k,\kfSlL} % \DoNotIndex{\L,\let} % \DoNotIndex{\message,\mHNa,\mIU} % \DoNotIndex{\N,\nB,\newcmykcolor,\newdimen,\newif,\nW} % \DoNotIndex{\O,\oCDJDo,\ocQhVI,\OnlyDescription,\oRKJ} % \DoNotIndex{\P,\p,\ProvidesPackage,\psframe,\pslinewidth,\psset} % \DoNotIndex{\PstAtCode,\PSTricksLoaded} % \DoNotIndex{\q,\Qr,\qssRXq,\qu,\qXjFQp,\qYL} % \DoNotIndex{\R,\r,\RecordChanges,\relax,\RlaYI,\rN,\Rp,\rp,\RPDXNn,\rput} % \DoNotIndex{\S,\scalebox,\SgY,\SideBySide@Example,\SideBySideExample} % \DoNotIndex{\SgY,\sk,\Sp,\space,\sZb} % \DoNotIndex{\T,\the,\tw@} % \DoNotIndex{\u,\UiSWGEf@,\uJi,\usepackage,\uVQdMM,\UYj} % \DoNotIndex{\VerbatimEnvironment,\VerbatimInput,\VrC@} % \DoNotIndex{\WhZ,\WjKCYb,\WNs} % \DoNotIndex{\XkN,\XW} % \DoNotIndex{\Z,\ZCM,\Ze} % \DoNotIndex{\addtocounter,\advance,\alph,\arabic,\AtBeginDocument,\AtEndDocument} % \DoNotIndex{\AtEndOfPackage,\begingroup,\bfseries,\bgroup,\box,\csname} % \DoNotIndex{\else,\endcsname,\endgroup,\endinput,\expandafter,\fi} % \DoNotIndex{\TeX,\z@,\p@,\@one,\xdef,\thr@@,\string,\sixt@@n,\reset,\or,\multiply,\repeat,\RequirePackage} % \DoNotIndex{\@cclvi,\@ne,\@ehpa,\@nil,\copy,\dp,\global,\hbox,\hss,\ht,\ifodd,\ifdim,\ifcase,\kern} % \DoNotIndex{\chardef,\loop,\leavevmode,\ifnum,\lower} % \setcounter{IndexColumns}{2} % % \let\pstIIIDFileVersion\fileversion % \let\pstIIIDFileDate\filedate % \newcommand{\PstIIIDPackage}{`\textsf{pst-3d}'} % \newcommand{\PstIIIDMacro}{\cs{Pst3d}} % % ^^A From ltugboat.cls % % ^^A Typeset the name of an environment % \providecommand\env[1]{\textsf{#1}} % \providecommand\clsname[1]{\textsf{#1}} % \providecommand\pkgname[1]{\textsf{#1}} % \providecommand\optname[1]{\textsf{#1}} % \providecommand\progname[1]{\textsf{#1}} % % ^^A A list of options for a package/class % \newenvironment{optlist}{\begin{description}% % \renewcommand\makelabel[1]{% % \descriptionlabel{\mdseries\optname{##1}}}% % \itemsep0.25\itemsep}% % {\end{description}} % % \makeatletter % % ^^A Utility macros % % ^^A Example macros - adapted from the `fvrb-ex' package % ^^A --------------------------------------------------- % % ^^A Take care that we use here the four /?_Z characters as escape % ^^A characters, so we can't use these characters in the examples! % % ^^A To highlight some verbatim sequences (comments, macro names, etc.) % \def\HLEmphasize#1{\textit{#1}} % \newcommand{\BS}{\texttt{\symbol{`\\}}} % \def\HLMacro#1{\BS{}def\HLMacro@i#1\@nil} % \def\HLMacro@i#1def#2\@nil{\HLReverse{#2}} % \def\HLReverse#1{{\setlength{\fboxsep}{1pt}\HLReverse@i{#1}}} % \def\HLReverse@i#1{\colorbox{black}{\textcolor{white}{\textbf{#1}}}} % % \def\Example{\FV@Environment{}{Example}} % \def\endExample{% % \end{VerbatimOut} % \Below@Example{\input{\jobname.tmp}} % \endgroup} % % \def\CenterExample{\FV@Environment{}{Example}} % \def\endCenterExample{% % \end{VerbatimOut} % \begin{center} % \Below@Example{\input{\jobname.tmp}} % \end{center} % \endgroup} % % \def\SideBySideExample{\FV@Environment{}{Example}} % \def\endSideBySideExample{% % \end{VerbatimOut} % \SideBySide@Example{\input{\jobname.tmp}} % \endgroup} % % \def\FVB@Example{% % \begingroup % \FV@UseKeyValues % \parindent=0pt % \multiply\topsep by 2 % \VerbatimEnvironment % \begin{VerbatimOut}[gobble=4,codes={\catcode`\Z=12}]{\jobname.tmp}} % % \def\Below@Example#1{% % \VerbatimInput[gobble=0,commentchar=Z,commandchars=/?_,frame=single, % numbers=left,numbersep=3pt]{\jobname.tmp} % \catcode`\%=14\relax % \catcode`\Z=9\relax % ^^A We suppress the effect of the highlighting macros % \catcode`/=0\relax % \catcode`?=1\relax % \catcode`_=2\relax % \def\HLEmphasize##1{##1}% % \def\HLMacro##1{##1}% % \def\HLReverse##1{##1}% % #1 % \par} % % \def\SideBySide@Example#1{% % \vskip 1mm % \@tempdimb=\FV@XRightMargin % \advance\@tempdimb -5mm % \begin{minipage}[c]{\@tempdimb} % \fvset{xrightmargin=0pt} % \catcode`\%=14\relax % \catcode`\Z=9\relax % ^^A We suppress the effect of the highlighting macros % \catcode`/=0\relax % \catcode`?=1\relax % \catcode`_=2\relax % \def\HLEmphasize##1{##1}% % \def\HLMacro##1{##1}% % \def\HLReverse##1{##1}% % #1 % \end{minipage}% % \@tempdimb=\textwidth % \advance\@tempdimb -\FV@XRightMargin % \advance\@tempdimb 5mm % \begin{minipage}[c]{\@tempdimb} % \VerbatimInput[gobble=0,commentchar=Z,commandchars=/?_, % frame=single,numbers=left,numbersep=3pt, % xleftmargin=5mm,xrightmargin=0pt]{\jobname.tmp} % \end{minipage} % \vskip 1mm} % % ^^A End of example macros from `fvrb-ex' % % ^^A Customizations of the "Verbatim" environment % \RecustomVerbatimEnvironment{Verbatim}{Verbatim}% % {gobble=4,frame=single,numbers=left,numbersep=3pt,commandchars=/?_} % % ^^A For the possible index and changes log % \setlength{\columnseprule}{0.6pt} % % % \def\PiCTeX{PiC\TeX} % \def\arc{\texttt{arc}} % \def\sign{\texttt{sign}} % % ^^A Beginning of the documentation itself % % \title{The \PstIIIDPackage{} package\\Tilting and other pseudo-3D tricks with PSTricks} % \author{Timothy Van Zandt\\ % Herbert Vo\ss} % \date{Version \pstIIIDFileVersion\ \pstIIIDFileDate\ \\ % {\small Documentation revised \today\ (hv)}} % % \maketitle % % \begin{abstract} % \texttt{pst-3d} provides basic macros for shadows, tilting and % three dimensional representations of text or graphical objects. % \end{abstract} % % \clearpage % \tableofcontents % % \section{introduction} % % The base package \texttt{pstricks} already disposes of some macros with which three % dimensional effects can be obtained. % There are several packages though which support the creation of three % dimensional objects or functions. A compilation is shown in % table~\ref{tab:pst3d:pakete}. Here already several of the packages overlap, for % parallel developments are nothing unusual in the \TeX{} world. Although % \verb+pst-3d+ is one of the older packages, it shall be dealt with nevertheless, % for it also contains the preliminary stage of the 3D representations, that is % shadow creation and tilting. % % \begin{table}[htb] % \caption{Summary of all 3D packages}\label{tab:pst3d:pakete} % \centering % \begin{tabular}{ll} % \emph{package} & \emph{content}\\\hline % \texttt{pst-3d} & basic 3D operations\\ % \texttt{pst-3dplot} & Three dimensional plots\\ % \texttt{pst-fr3d} & Three dimensional framed Boxes\\ % \texttt{pst-gr3d} & 3D grids\\ % \texttt{pst-map3dII}& 3D Geographical Projection\\ % \texttt{pst-ob3d} & Three dimensional basic objects\\ % \texttt{pst-vue3d} & Three dimensional views\\ % \end{tabular} % \end{table} % % % \section{Shadow}\label{sec:pst3d:schattenwurf} % \verb+pst-3d+ defines the macro \verb+\psshadow+ with the following syntax: % \begin{verbatim} % \psshadow[]{] % \end{verbatim} % As parameters the ones given in table~\ref{tab:pst-3d:schattenparameter} are % available next to all previously defined, if they have a meaning for the % material to be shadowed. This can be anything text-like, text, rules and % mathematical expressions in inline mode. % % \medskip % \begin{SideBySideExample}[xrightmargin=.35\linewidth] % \newgray{gray75}{.75} % \psset{Tshadowcolor=gray75} % \psshadow{\huge Shadow}\\[10pt] % \psshadow{\huge $f(x)=x^2$}\\[15pt] % \psshadow[Tshadowsize=2.5]{% % \rule{2cm}{10pt}} % \end{SideBySideExample} % % \subsection{Parameters}\label{subsec:pst3d:schattenparameter} % Table~\ref{tab:pst-3d:schattenparameter} shows a compilation of the used % parameters. % % % % % \begin{table}[htb] % \caption{Summary of all \texttt{shadow} parameters}\label{tab:pst-3d:schattenparameter} % \centering % \begin{tabular}{>{\ttfamily}l>{\ttfamily}l>{\ttfamily}l} % \textrm{\emph{name}} & \textrm{\emph{values}} & \textrm{\emph{default}}\\\hline % Tshadowangle & & 60\\ % Tshadowcolor & & lightgray\\ % Tshadowsize & & 1 % \end{tabular} % \end{table} % % % \subsubsection{\texttt{Tshadowangle}}\label{subsubsec:pst3d:tshadowangle} % \verb+Tshadowangle+ denotes the angle of the shadow, % referring to the perpendicular of the paper plane. The angle of $90$° therewith % corresponds to the text itself. Negative angles cause the shadow to arise % from the paper plane. % \medskip % \begin{SideBySideExample}[xrightmargin=.25\linewidth] % \newgray{gray75}{.75} % \psset{Tshadowcolor=gray75} % \psshadow{\huge shadow}\\[5pt] % \psshadow[Tshadowangle=30]{\huge shadow}\\[5pt] % \psshadow[Tshadowangle=70]{\huge shadow}\\[5pt] % \psshadow[Tshadowangle=-30]{\huge shadow} % \end{SideBySideExample} % % \medskip % \begin{itemize} % \item Angular values of $0$° and $180$° are not allowed. % \end{itemize} % % % % \subsubsection{\texttt{Tshadowcolor}}\label{subsubsec:pst3d:tshadowcolor} % \verb+Tshadowcolor+ deontes the shadow colour. % % \begin{SideBySideExample}[xrightmargin=.25\linewidth] % \psshadow{\huge shadow}\\[5pt] % \psshadow[Tshadowcolor=red]{\huge shadow}\\[5pt] % \psshadow[Tshadowcolor=green]{\huge shadow}\\[5pt] % \psshadow[Tshadowcolor=blue]{\huge shadow} % \end{SideBySideExample} % % % \subsubsection{\texttt{Tshadowsize}}\label{subsubsec:pst3d:tshadowsize} % \verb+Tshadowsize+ determines the size of the % shadow\index{shadow!size} as a scaling factor\index{scaling factor}. % % \begin{SideBySideExample}[xrightmargin=.25\linewidth] % \psshadow{\Huge shadow}\\[5pt] % \psshadow[Tshadowsize=0.5]{\Huge shadow}\\[10pt] % \psshadow[Tshadowsize=1.5]{\Huge shadow}\\[20pt] % \psshadow[Tshadowsize=2.5]{\Huge shadow} % \end{SideBySideExample} % % % % % % \section{Tilting}\label{sec:pst3d:kippen} % With the tilting of objects the % perspective views of three dimensional objects can be simulated. \verb+pst-3d+ % defines two macros for this. % % \begin{verbatim} % \pstilt[]{}{} % \psTilt[]{}{} % \end{verbatim} % % Figure~\ref{fig:pst3d:demo} shows the difference between these two macros. % Principally everything can be given as argument to those macros and therewith % tilted. With vertical material, as distinguished formulae, eventually the % argument has to be put into a \verb+\parbox+ before (see % example), % % \begin{figure}[htb] % \centering % \bgroup % \begin{pspicture}(0,-0.2)(9,3) % \psline[linestyle=dashed](0,2)(9,2) % \psline{->}(9,0) % \def\Bar{\psframe*[linecolor=lightgray](0,0)(0.5,2)} % \rput(0.5,0){\Bar} % \psset{arrowscale=2,linewidth=0.1pt,tbarsize=2mm} % \psline{|<->|}(0.25,0)(0.25,2)\rput*{90}(0.25,1){\small 2cm} % \rput(2,0){\psTilt{30}{\Bar}} % \psarc{->}(2.2,0){2}{0}{26}\rput(4.5,0.5){30°} % \pnode(2,0.3){A}\pnode(5.3,2.25){B} % \ncline{|<->|}{A}{B}\ncput*[nrot=:U]{\small 4cm} % \rput(6,0){\pstilt{30}{\Bar}} % \psarc{->}(6.2,0){2}{0}{26}\rput(8.5,0.5){30°} % \pnode(6,0.3){A}\pnode(7.65,1.25){B} % \ncline{|<->|}{A}{B}\ncput*[nrot=:U]{\small 2cm} % \uput[90](0.5,2.5){\cs{Bar}} % \uput[90](3.75,2.5){\cs{psTilt\{30\}\{\textbackslash Bar\}}} % \uput[90](7.25,2.5){\cs{pstilt\{30\}\{\textbackslash Bar\}}} % \end{pspicture} % \egroup % \caption{Demonstration of the difference between \cs{pstilt} and \cs{psTilt}}\label{fig:pst3d:demo} % \end{figure} % % \medskip % \begin{itemize} % \item Angular values of $0$\textdegree\ and $180$\textdegree\ are not allowed. % \end{itemize} % % \subsection{\cs{pstilt}}\label{subsec:pst3d:pstilt} % \verb+\pstilt+ tilts objects that their original height appears % as new length of the tilted object, wherewith the object becomes smaller. The % hynotenuse of the triangle from nadir, height and perpendicular now corresponds % to the old height (see figure~\ref{fig:pst3d:demo}). At this the length is % calculated from the middle of the base side. % % % \medskip\noindent % \begin{SideBySideExample}[xrightmargin=.4\linewidth] % \def\Bar{\psframe(0,0)(0.25,2)} % \begin{pspicture}(5,2) % \multido{\nA=15+15}{11}{\rput(2.5,0){% % \pstilt{\nA}{\Bar}}} % \end{pspicture} % \end{SideBySideExample} % % % % \medskip\noindent % \begin{SideBySideExample}[xrightmargin=.4\linewidth] % \pstilt{60}{% % \begin{pspicture}(-0.5,-0.5)(2,2) % \psaxes[axesstyle=frame](2,2) % \end{pspicture}} % \end{SideBySideExample} % % % \medskip\noindent % \begin{SideBySideExample}[xrightmargin=.4\linewidth] % \newpsstyle{TCyan}{% % fillstyle=vlines,hatchcolor=cyan, % hatchwidth=0.1\pslinewidth,% % hatchsep=1.5\pslinewidth} % \begin{pspicture}(2,4) % \rput[lb](0,0){\pstilt{45}{% % \psframe[linestyle=dashed,% % fillstyle=solid,fillcolor=red](2,4)}} % \psframe[style=TCyan](0,0)(2,4) % \end{pspicture} % \end{SideBySideExample} % % % \medskip % With the package \verb+rotating+ macros to rotate text are % provided, to achieve slant table headings for example. It is more difficult when % they are provided with a frame. With \cs{pstilt} or \cs{psTilt} this is no % problem. The program listing given below only shows the application of % \cs{pstilt} for the macro only has to be replaced by \cs{psTilt} to obtain the % other example. % \begin{SideBySideExample}[xrightmargin=.3\linewidth] % \begin{tabular}{l} % \pstilt{60}{% % \begin{tabular}{|p{1em}|p{1em}|p{1em}|}\hline % \psrotateleft{column 1\ } % & \psrotateleft{column 2\ } % & \psrotateleft{column 3\ } % \end{tabular}}\\ % \begin{tabular}{|p{1em}|p{1em}|p{1em}|}\hline % 1 & 2 & 3 \\\hline % 4 & 5 & 6 \\\hline % \end{tabular} % \end{tabular} % \end{SideBySideExample} % % % \subsection{\cs{psTilt}}\label{subsec:pst3d:psTilt} % \verb+\psTilt+ tilts objects that their original height is % preserved, so that the object could become infinitely long in theory (see % figure~\ref{fig:pst3d:demo}). % % % \medskip\noindent % \begin{CenterExample} % \begin{pspicture}(5,2) % \def\Bar{\psframe(0,0)(0.25,2)} % \multido{\nA=15+15}{11}{\rput(2.5,0){% % \psTilt{\nA}{\Bar}}} % \end{pspicture} % \end{CenterExample} % % % % \medskip\noindent % \begin{SideBySideExample}[xrightmargin=.4\linewidth] % \psTilt{60}{% % \begin{pspicture}(-0.5,-0.5)(2,2) % \psaxes[axesstyle=frame](2,2) % \end{pspicture}} % \end{SideBySideExample} % % % \medskip\noindent % \begin{SideBySideExample}[xrightmargin=.475\linewidth] % \newpsstyle{TCyan}{% % fillstyle=vlines,hatchcolor=cyan, % hatchwidth=0.1\pslinewidth,% % hatchsep=1.5\pslinewidth} % \begin{pspicture}(2,4) % \rput[lb](0,0){\psTilt{45}{% % \psframe[linestyle=dashed,% % fillstyle=solid,% % fillcolor=red](2,4)}} % \psframe[style=TCyan](0,0)(2,4) % \end{pspicture} % \end{SideBySideExample} % % % \section[Three dimensional representations]{% % Three dimensional representations\protect\footnote{Some of the examples were created by Manuel Luque.}}\label{sec:pst3d:3d} % % % \verb+pst-3d+ only supports parallel projections, so that geometrical objects % such as spheres or cylinders can only be displayed restricted. Although % \verb+pst-3d+ principally only defines one single macro for the 3D % projection, the package is very efficient in its % application and is also used as a base for other packages.\cite{pst-3dplot}\cite{pst-vue3d} % % \subsection{\cs{ThreeDput}}\label{subsec:pst3d:threedput} % \verb+pst-3d+ only defines this single macro, which can be % used to arbitrarily display line or area shaped objects in the three dimensional % space in the end though. % % \begin{verbatim} % \ThreeDput[]{} % \ThreeDput[](){} % \end{verbatim} % % Without a specification of coordinates, $(0,0,0)$ is taken as origin of % ordinates as a rule. As ``material''{} anything is understood that can be put % into a box. If it is vertical material in the \TeX{} sense, it has to be put in % a \verb+\parbox+ or \verb+minipage+ before. % % To simplify the specified source code, the macro \verb+\IIIDKOSystem+ is used in % the following, which draws the coordinate axes with the grid and is not % specified in the following anymore. % % % \makeatletter % \newgray{gray75}{0.75}\newgray{gray80}{0.80}newgray{gray85}{0.85} % \newgray{gray90}{0.90}\newgray{gray95}{0.95} % \def\xyPlain#1{% % \ThreeDput[normal=0 0 1](0,0,0){% % \psgrid[subgriddiv=0,gridcolor=lightgray](0,0)(#1,#1)% % \psline{->}(0,0)(0,#1)\psline{->}(0,0)(#1,0)% % \ifdim\psk@gridlabels pt>\z@ % \uput[180]{0.2}(0,#1){$y$}\uput[-90]{0.2}(#1,0){$x$}\fi}} % \def\xzPlain#1{% % \ThreeDput[normal=0 -1 0](0,0,0){% % \psgrid[subgriddiv=0,gridcolor=lightgray](0,0)(#1,#1)% % \psline{->}(0,0)(0,5) \psline{->}(0,0)(#1,0)% % \ifdim\psk@gridlabels pt>\z@% % \uput[180]{0.2}(0,#1){$z$}\uput[-90]{0.2}(#1,0){$x$}% % \fi}} % \def\yzPlain#1{% % \ThreeDput[normal=1 0 0](0,0,0){% % \psgrid[subgriddiv=0,gridcolor=lightgray](0,0)(#1,#1)% % \psline{->}(0,0)(0,#1) \psline{->}(0,0)(#1,0)% % \ifdim\psk@gridlabels pt>\z@% % \uput[180]{0.2}(0,#1){$z$}\uput[-90]{0.2}(#1,0){$y$}% % \fi}} % \def\IIIDKOSystem{\@ifnextchar[{\IIIDKOSystem@i}{\IIIDKOSystem@i[]}} % \def\IIIDKOSystem@i[#1]#2{% % \psset{#1}% % \xyPlain{#2}\xzPlain{#2}\yzPlain{#2}} % \makeatother % % \medskip\noindent % \begin{CenterExample} % \makeatletter % \def\xyPlain#1{% % \ThreeDput[normal=0 0 1](0,0,0){% xy-plane % \psgrid[subgriddiv=0,gridcolor=lightgray](0,0)(#1,#1) % \psline{->}(0,0)(0,#1) \psline{->}(0,0)(#1,0) % \ifdim\psk@gridlabels pt>\z@ % \uput[180]{0.2}(0,#1){$y$}\uput[-90]{0.2}(#1,0){$x$}\fi }} % \def\xzPlain#1{% % \ThreeDput[normal=0 -1 0](0,0,0){% xz-plane % \psgrid[subgriddiv=0,gridcolor=lightgray](0,0)(#1,#1) % \psline{->}(0,0)(0,5) \psline{->}(0,0)(#1,0) % \ifdim\psk@gridlabels pt>\z@ % \uput[180]{0.2}(0,#1){$z$}\uput[-90]{0.2}(#1,0){$x$}% % \fi }} % \def\yzPlain#1{% % \ThreeDput[normal=1 0 0](0,0,0){% yz-plane % \psgrid[subgriddiv=0,gridcolor=lightgray](0,0)(#1,#1) % \psline{->}(0,0)(0,#1) \psline{->}(0,0)(#1,0) % \ifdim\psk@gridlabels pt>\z@ % \uput[180]{0.2}(0,#1){$z$}\uput[-90]{0.2}(#1,0){$y$}% % \fi }} % \def\IIIDKOSystem{\@ifnextchar[{\IIIDKOSystem@i}{\IIIDKOSystem@i[]}} % \def\IIIDKOSystem@i[#1]#2{% % \psset{#1}% % \xyPlain{#2}\xzPlain{#2}\yzPlain{#2}} % \makeatother % \newgray{gray75}{0.75} % \newgray{gray80}{0.8} % \newgray{gray85}{0.85} % \newgray{gray95}{0.95} % \begin{pspicture}(0,-1.25)(5,6) % \psset{viewpoint=1 -1 0.75} % \IIIDKOSystem{5} % \ThreeDput{\psframe*[linecolor=gray80](3,3)} % \ThreeDput(1.5,1.5,0){\Huge below} % \ThreeDput(0,0,1.5){\psframe*[linecolor=gray75](3,3)} % \ThreeDput(1.5,1.5,1.5){\Huge center} % \ThreeDput(0,0,3){\psframe*[linecolor=gray85](3,3)} % \ThreeDput(1.5,1.5,3){\Huge above} % \xzPlain{5} % \ThreeDput(4,4,0){\psframe*[linecolor=gray95](-1,-1)(1,1)} % \ThreeDput(4,4,0){\psdot[dotscale=3]} % \end{pspicture} % \end{CenterExample} % % % The coordinates of \verb+ThreeDput+ refer to the centre of the object, which % does not necessarily need to be the geometrical centre. % \begin{verbatim} % \psframe(2,2)% centre bottom left (0,0) % \psframe(-1,-1(1,1)% centre in the middle (0,0) % arbitrary text% centre in the middle of the base line % \end{verbatim} % % In the above example the smaller square with its centre $(0,0)$ has been set % exactly to the coordinated $(4,4,0)$. % The macro \verb+ThreeDput+ can be manifoldly applied, which is performed % especially by the package \verb+pst-vue3d+\cite{pst-vue3d}. By % specifying the normal vector $\vec{n}$ and a point $P(x,y,z)$ of the stright % line and/or the plane the posture in space can be determined definitely. Areas % can be provided with different levels of brightness to increase the spatial % impression. % % % % \medskip\noindent % \begin{CenterExample} % \newgray{gray75}{0.75}\newgray{gray85}{0.85}\newgray{gray95}{0.95} % \begin{pspicture}(-4.5,-3.5)(3,4.75) % \psset{viewpoint=1 1.5 1} % \IIIDKOSystem[gridlabels=0pt,gridcolor=lightgray,subgriddiv=0]{5}% % \ThreeDput[normal=0 0 1]{% xy-plane % \psline[linewidth=3pt,linecolor=blue]{->}(4,4)(4,5.5)% % \uput[90](4,5.5){\color{blue}$\vec{n}-{A}$}}% % \ThreeDput[normal=0 -1 0]{% xz-plane % \psline[linewidth=3pt,linecolor=green]{->}(4,0)(5.5,0)% % \uput[90](5.5,0){\psscalebox{-1 1}{% % \textcolor{green}{$\vec{n}-B$}}}}% % \ThreeDput[normal=1 0 0]{% yz-plane % \psline[linewidth=3pt,linecolor=red]{->}(0,4)(0,5.5)% % \uput[0](0,5.5){$\vec{n}-{top}$}}% cube and axes % \ThreeDput[normal=0 0 1](0,0,4){% % \psframe*[linecolor=gray75](4,4)\rput(2,2){\Huge\textbf{TOP}}}% % \ThreeDput[normal=0 1 0](4,4,0){% % \psframe*[linecolor=gray95](4,4)\rput(2,2){\Huge\textbf{side A}}}% % \ThreeDput[normal=1 0 0](4,0,0){% % \psframe*[linecolor=gray85](4,4)\rput(2,2){\Huge\textbf{side B}}}% % \ThreeDput[normal=0 0 1](0,0,4){% % \psline(4,0)\uput[90](3,0){$X-top$}\psline(0,4)\uput[0](0,3){$Y-top$}}% % \ThreeDput[normal=0 1 0](4,4,0){% % \psline(4,0)\uput[90](3,0){$X-A$}\psline(0,4)\uput[0](0,3){$Y-A$}}% % \ThreeDput[normal=1 0 0](4,0,0){% % \psline(4,0)\uput[90](3,0){$X-B$}\psline(0,4)\uput[0](0,3){$Y-B$}}% % \end{pspicture} % \end{CenterExample} % % % \subsection{3D parameters}\label{subsec:pst3d:3dParameter} % Table~\ref{tab:pst-3d:3dparameter} shows a compilation of % the parameters which can be used to influence 3D representations. % % \begin{table}[htb] % \caption{Summary of all 3D parameters}\label{tab:pst-3d:3dparameter} % \begin{tabular}{>{\ttfamily}l>{\ttfamily}l>{\ttfamily}l} % \textrm{name} & \textrm{values} & \textrm{default}\\\hline % viewpoint & & 1 -1 1\\ % viewangle & & 0\\ % normal & & 0 0 1\\ % embedangle & & 0 % \end{tabular} % \end{table} % % \subsubsection{\texttt{viewpoint}}\label{subsubsec:pst3d:viewpoint} % The viewing direction to the 3D object influences the % representation essentially. With \verb+viewpoint+ the $(x,y,z)$ coordinates % which denote the vector of the viewing direction are specified. Because of the % parallel projection the length of this vector is unimportant, so that % \verb+(10.5 1.5)+ and \verb+(2 1 3)+ yield the same representations. % Figure~\ref{fig:pst3d:viewpoint} shows who somebody would regard this % representation, whereat the representation itself is of course regarded from % another point in this case, otherwise one had to look directly onto the vector. % % % \SpecialCoor % \def\oeil{% % \pscurve(1;160)(0.8;180)(1;200) % \pscustom{\gsave\psarc(0,0){1}{165}{195} % \pscurve(1;195)(0.85;180)(1;165) % \fill[fillstyle=solid,fillcolor=blue]\grestore} % \pscurve[linewidth=.4pt](1;195)(0.85;180)(1;165) % {\psset{linewidth=2pt} % \psarc(0,1){1}{180}{270} % \psarc(0,-1){1}{90}{180}} % \psarc(0,0){1}{150}{210} % \psset{linewidth=4pt,linecolor=gray} % \pscurve(-.5,3.5)(-1,3)(-1.2,2.5)(-1.3,2)(-1.4,1)(-1.35,0.5)(-1.2,-.2)(-1.35,-.5) % (-1.4,-1)(-1.5,-1.5)(-1.8,-2)(-1.8,-2.3)(-1.65,-2.5)(-1.35,-2.55)(-.95,-2.8) % (-.95,-3.35)(-1,-3.65)(-.8,-4)(-.4,-4.1) % \pscurve(-.8,-4)(-.8,-4.2)(-.5,-4.5)(-.4,-5)(-.25,-5.5)(0,-5.8)(.5,-6)} % % % \begin{figure}[htb] % \centering % \begin{pspicture}(-5,-1)(5,6) % \psset{viewpoint=3 5 2} % \psset{unit=2} % \ThreeDput[normal=0 0 1](0,0,0){% % \psline{->}(0,0)(2,0) % \uput[90](2,0){$x$} % \qdisk(1,0.5){2pt} % \psline(1,0)(1,0.5)\psline(1,0.5)(0,0.5) % \psline[linestyle=dotted](0,0)(1,0.5) % \psset{fillstyle=solid,fillcolor=lightgray,linestyle=none} % \psframe(1,0)(1.15,.15) % \psframe(0,.5)(.15,.65)} % \ThreeDput[normal=1 0 0](0,0,0){% % \psline{->}(0,0)(2,0) % \uput[90](2,0){$y$} % \psline{->}(0,0)(0,2) % \uput[180](0,2){$z$} % \uput[90](0.5,0){0.5} % \uput[180](0,1.5){1.5} % \uput[135](0,0){0} % \rput(1.2,1.5){\large 3D representations}} % \ThreeDput[normal=0 1 0](0,0,0){% % \uput[90](-2,0){$x$} % \uput[90](-1,0){1} % \rput(-1.5,1){\texttt{pst-3d}}} % \ThreeDput[normal=.5 -1 0](0,0,0){% % \psframe[linestyle=none,fillstyle=hlines,hatchwidth=0.1pt, % hatchsep=2pt,hatchcolor=gray90](0,0)(1.118,1.5) % \psline[linewidth=3pt,linecolor=red,arrowinset=0]{->}(0,0)(1.118,1.5) % \psline[linestyle=dashed](0,0)(2.236,3) % \psline(1.118,0)(1.118,1.5) % \psline(1.118,1.5)(0,1.5) % \rput{53.3}(2.5348,3.4009){\psscalebox{0.2}{\oeil}}} % \end{pspicture} % \caption{Definition of the \texttt{viewpoints}}\label{fig:pst3d:viewpoint} % \end{figure} % % % For figure~\ref{fig:pst3d:viewpoint} a viewpoint of \verb+viewpoint=3 5 2+ was % defined. If one desires to regard it for instance from the $y$ axis from a % larger height, \verb+viewpoint=0 1 3+ could be chosen. The viewer has moved one % unit in $y$ direction and four units in $z$ direction from the centre (origin) % and regards everything from there. % % % \medskip % \begin{itemize} % \item The \verb+viewpoint+ principally \textbf{has} to be defined with % values not equal to zero, for this would lead to a division by zero. % Specifications of $0.001$ for a coordinate are already sufficing to % escape the division by zero and blind out the coordinate. % \end{itemize} % % A good value for the viewpoint would be \verb+viewpoint=1 1 0.5+ for instance, % which corresponds to a horizontal rotation by 45° and a vertical by ca. 20°. % Another meaningful point is also \verb+viewpoint=1.5 1 0.5+, which now % corresponds to a horizontal rotation by 33° and the same vertical rotation. Both % can be seen in the examples below. % % \medskip % \begin{CenterExample} % \begin{pspicture}(-3,-2.5)(-3,4) % \psset{unit=0.75} % \psset{viewpoint=1 1 0.5} % \IIIDKOSystem{5} % \end{pspicture}\hfill % \begin{pspicture}(-3,-2.5)(2.2,4) % \psset{unit=0.75} % \psset{viewpoint=1 1.5 0.5} % \psset{gridlabels=6pt} % \IIIDKOSystem{5} % \end{pspicture} % \end{CenterExample} % % % \subsubsection{\texttt{viewangle}}\label{subsubsec:pst3d:viewangle} % Additional to the \verb+viewpoint+ option one can rotate the object by another % option called \verb+viewangle+. This could also be done by the macro \verb+\rotatebox+, % but \verb+viewangle+ has some advantages . % % % \bigskip\noindent % \begin{CenterExample} % \begin{pspicture}(-1,-2.5)(4,4) % \psset{unit=0.7,viewpoint=1 1 0.5,viewangle=20} % \IIIDKOSystem{5} % \ThreeDput(0,0,0){\psframe*[linecolor=gray80](4,4)} % \ThreeDput(2,2,0){\Huge Unten} % \end{pspicture} % \begin{pspicture}(-3,-2.5)(1,4) % \psset{unit=0.7,viewpoint=1 1.5 0.5,viewangle=-30} % \IIIDKOSystem{5} % \ThreeDput(0,0,0){\psframe*[linecolor=gray80](4,4)} % \ThreeDput(2,2,0){\Huge Unten} % \end{pspicture} % \end{CenterExample} % % % \subsubsection{\texttt{normal}}\label{subsubsec:pst3d:normal} % \verb+normal+ denotes the direction of the normal % vector which is perpendicular to a corresponding area. % Therewith the posture of an object in three dimensional space is definitely % determined by the normal vector. % % \medskip\noindent % \begin{CenterExample} % \newgray{gray75}{0.75}\newgray{gray85}{0.85}\newgray{gray95}{0.95} % \begin{pspicture}(-3.5,-2.5)(-3,5) % \psset{viewpoint=1 1.5 0.5} % \IIIDKOSystem{5} % \ThreeDput(0,0,0){\psframe*[linecolor=gray80](4,4)} % \ThreeDput(2,2,0){\huge\psrotatedown{xy-plane}} % \ThreeDput[normal=0 -1 0](0,0,0){\psframe*[linecolor=gray85](4,4)} % \ThreeDput[normal=0 1 0](2,0,2){\huge xz-plane} % \ThreeDput[normal=1 0 0](0,0,0){\psframe*[linecolor=gray90](4,4)} % \ThreeDput[normal=1 0 0](0,2,2){\huge yz-plane} % \ThreeDput[normal=0 0 1](0,0,0){% xy-plane % \psline{->}(0,0)(0,5)\psline{->}(0,0)(5,0)} % \ThreeDput[normal=0 1 0](0,0,0){\psline{->}(0,0)(0,5)} % \end{pspicture} % \end{CenterExample} % % % Without a assignment through the normal vector the above example could not have % been created that easily. Let us step through the code for a better % understanding. % % \begin{description} % \item[\cs{psset\{viewpoint=1 1.5 0.5\}}:] the % \verb+viewpoint+ is set to the point $P(1,1.5,0.5)$. % \item[\cs{IIIDKOSystem\{5\}}:] first the coordinate system with the grid is % drawn, so that axes and grid remain visible on the areas, which makes a % better optical allocation possible. % \item[\cs{ThreeDput(0,0,0)\{\textbackslash psframe*[linecolor=gray80](4,4)\}}:] % puts a square with a side length of four into the origin of ordinates with % the lower left edge. Since no normal vector is specified here, the default % value $\vec{n}=(0,0,1)$ is taken, wherewith the area is positioned in the % first quadrant of the $xy$ plane. % \item[\cs{ThreeDput(2,2,0)\{\textbackslash huge\textbackslash psrotatedown\{xy-plane\}\}}:] % puts the text rotated by $180$° centric to the point $(2,2,0)$ in the % \verb+xy-plane+. % \item[\cs{ThreeDput[normal=0 -1 0](0,0,0)\{\textbackslash psframe*[linecolor=gray85](4,4)\}}:] % puts a square with a side length of four in the origin of ordinates with the % lower left edge. Since the normal vector is the ``negative''{} $y$ axis, the % square is positioned in the first quadrant of the $xz$ plane. With % \verb+normal=0 1 0+ it would have been the second quadrant. % \item[\cs{ThreeDput[normal=0 1 0](2,0,2)\{\textbackslash huge xz-plane\}}:] % puts the text in the \verb+xy-plane+ centric to the point $(2,0,2)$. Because % the $xz$ plane is regarded from the back from the viewpoint, the normal % vector of the area has to be reversed, otherwise the text would be read from % the ``back''{}. % \item[\cs{ThreeDput[normal=1 0 0](0,0,0)\{\textbackslash psframe*[linecolor=gray90](4,4)\}}:] % puts a square with a side length of four in the origin of ordinates with the % lower left edge. The unit vector is the ``positive''{} $x$ axis, therefore % the square is positioned in the first quadrant of the $yz$ plane. % \item[\cs{ThreeDput[normal=1 0 0](0,2,2)\{\textbackslash huge yz-plane\}}:] % puts the text in the \verb+yz-plane+ centric to the point $(0,2,2)$. Since % the text is written at the ``positive''{} side of the area, the normal % vector stays the same. % \item[\cs{ThreeDput[normal=0 0 1](0,0,0)}:] the coordinate axes have been % overwritten by the three areas and are redrawn now, first the $xy$ axes. % \item[\cs{ThreeDput[normal=0 1 0](0,0,0)}:] and now the $z$ axis is drawn. % \end{description} % % \subsubsection{\texttt{embedangle}}\label{subsubsec:pst3d:embedangle} % With \verb+viewangle+ a rotation perpendicular to the plane % of the viewer could be made. With \verb+embedangle+ a rotation perpendicular to % the normal vector can be made. The counting of the angles is made in the % mathematical sense, counterclockwise. % % \medskip % \begin{CenterExample} % \newgray{gray75}{0.75}\newgray{gray85}{0.85}\newgray{gray95}{0.95} % \def\tBlack#1#2{% % \psframe[style=#2](2,2) % \rput(1,1){\textcolor{#1}{\textbf{PSTricks}}}} % \newpsstyle{SolidYellow}{fillstyle=solid,fillcolor=yellow} % \newpsstyle{TransparencyRed}{fillstyle=vlines,hatchcolor=red, % hatchwidth=0.1\pslinewidth,hatchsep=1\pslinewidth} % \newpsstyle{TransparencyBlue}{fillstyle=vlines,hatchcolor=gray75,% % hatchwidth=0.1\pslinewidth,hatchsep=1\pslinewidth} % \begin{pspicture}(-1.2,-1.75)(4.8,3.7) % \ThreeDput{\psgrid[subgriddiv=0](-2,0)(4,3)} % \ThreeDput(-1,0,0){\tBlack{black}{SolidYellow}} % \ThreeDput(2,0,0){\tBlack{black}{SolidYellow}} % \ThreeDput[embedangle=50](-1,0,0){\tBlack{gray}{TransparencyRed}} % \ThreeDput[embedangle=50](2,0,0){\tBlack{gray}{TransparencyBlue}} % \ThreeDput[normal=0 1 0](-1,0,0){\psline[linewidth=0.1,linecolor=red](0,4)} % \ThreeDput[normal=0 1 0](2,0,0){\psline[linewidth=0.1,linecolor=blue](0,4)} % \end{pspicture} % \psset{viewpoint=1 1 100} % \begin{pspicture}(-2.5,-4.5)(2.8,1.7) % \ThreeDput{\psgrid[subgriddiv=0](-2,0)(4,3)} % \ThreeDput(-1,0,0){\tBlack{black}{SolidYellow}} % \ThreeDput(2,0,0){\tBlack{black}{SolidYellow}} % \ThreeDput[embedangle=50](-1,0,0){\tBlack{gray}{TransparencyRed}} % \ThreeDput[embedangle=50](2,0,0){\tBlack{gray}{TransparencyBlue}} % \ThreeDput[normal=0 1 0](-1,0,0){\psline[linewidth=0.1,linecolor=red](0,4)} % \ThreeDput[normal=0 1 0](2,0,0){\psline[linewidth=0.1,linecolor=blue](0,4)} % \end{pspicture} % \end{CenterExample} % % % \StopEventually{} % % ^^A .................... End of the documentation part .................... % % \section{Driver file} % % The next bit of code contains the documentation driver file for \TeX{}, % i.e., the file that will produce the documentation you are currently % reading. It will be extracted from this file by the \texttt{docstrip} % program. % % % \section{\PstIIIDPackage{} \LaTeX{} wrapper} % % \begin{macrocode} %<*latex-wrapper> %% \RequirePackage{pstricks} \ProvidesPackage{pst-3d}[2005/09/02 package wrapper for pst-3d.tex (hv)] \input{pst-3d.tex} \ProvidesFile{pst-3d.tex} [\filedate\space v\fileversion\space `PST-3d' (tvz)] % % \end{macrocode} % % \section{\PstIIIDPackage{} code} % %<*pst-3d> % % \verb+pst-3d+ Require the basic \verb+pstricks+ package and for the key value % operations the \verb+pst-xkey+ package. % % \begin{macrocode} \ifx\PSTricksLoaded\endinput\else\input pstricks.tex\fi \ifx\PSTXKeyLoaded\endinput\else\input pst-xkey \fi % (hv 2005-09-03) % \end{macrocode} % % Catcodes changes. % % \begin{macrocode} \edef\PstAtCode{\the\catcode`\@} \catcode`\@=11\relax % \end{macrocode} % % Add the key-family name to the xkeyval package % % \begin{macrocode} \pst@addfams{pst-3d} % \end{macrocode} % \def\fileversion{1.00} \def\filedate{2005/09/03} \message{`PST-3d' v\fileversion, \filedate\space (tvz)} % % Mark the package as loaded % % \begin{macrocode} \csname PSTthreeDLoaded\endcsname \let\PSTthreeDLoaded\endinput % \end{macrocode} % % \subsection{Basic 3D transformations} % % \begin{macro}{\tx@SetMatrixThreeD} % Viewpoint for 3D coordinates is given by three angles: $\alpha$, $\beta$ and % $\gamma$. $\alpha$ and $\beta$ determine the direction from which one is % looking. $\gamma$ then determines the orientation of the observing. % When $\alpha$, $\beta$ and $\gamma$ are all zero, the observer is looking % from the negative part of the $y$-axis, and sees the $xz$-plane the way in % 2D one sees the $xy$ plan. Hence, to convert the 3D coordinates to their 2D % project, $\langle x, y, z\rangle$ map to $\langle x, z\rangle$. % When the orientation is different, we rotate the coordinates, and then % perform the same projection. % We move up to latitude $\beta$, over to longitude $\alpha$, and then rotate % by $\gamma$. This means that we first rotate around $y$-axis by $\gamma$, % then around $x$-axis by $\beta$, and the around $z$-axis by $\alpha$. % % Here are the matrices: % \begin{eqnarray*} % R_z(\alpha) & = & \left[ % \begin{array}{ccc} % \cos \alpha & -\sin \alpha & 0 \\ % \sin \alpha & cos \alpha & 0 \\ % 0 & 0 & 1 % \end{array} \right] \\ % R_x(\beta) & = & \left[ % \begin{array}{ccc} % 1 & 0 & 0 \\ % 0 & \cos \beta & \sin \beta \\ % 0 & -\sin \beta & \cos \beta % \end{array} \right] \\ % R_y(\gamma) & = & \left[ % \begin{array}{ccc} % \cos \gamma & 0 & -\sin \gamma \\ % 0 & 1 & 0 \\ % \sin \gamma & 0 & \cos \gamma % \end{array} \right] % \end{eqnarray*} % % The rotation of a coordinate is then performed by the matrix $R_z(\alpha) % R_x(\beta) R_y(\gamma)$. The first and third columns of the matrix are the % basis vectors of the plan upon which the 3D coordinates are project (the old % basis vectors were $\langle 1, 0, 0\rangle$ and $\langle 0, 0, 1\rangle$; rotating these % gives the first and third columns of the matrix). % % These new base vectors are: % \begin{eqnarray*} % \tilde{x} & = & \left[ % \begin{array}{c} % \cos\alpha \cos\gamma - \sin\beta \sin\alpha \sin\gamma \\ % \sin\alpha \cos\gamma + \sin\beta \cos\alpha \sin\gamma \\ % \cos\beta \sin\gamma % \end{array} \right] \\ % \tilde{z} & = & \left[ % \begin{array}{c} % -\cos\alpha \sin\gamma - \sin\beta \sin\alpha \cos\gamma \\ % -\sin\alpha \sin\gamma + \sin\beta \cos\alpha \cos\gamma \\ % \cos\beta \cos\gamma % \end{array} \right] % \end{eqnarray*} % % Rather than specifying the angles $\alpha$ and $\beta$, the user gives a % vector indicating where the viewpoint is. This new viewpoint is the rotation % o the old viewpoint. The old viewpoint is $\langle 0, -1, 0\rangle$, and so the new % viewpoint is % \[ % R_z(\alpha) R_x(\beta) \left[ \begin{array}{c} 0\\-1\\0 \end{array} \right] % \, = \, % \left[ \begin{array}{c} % \cos\beta \sin\alpha \\ % -\cos\beta \cos\alpha \\ % \sin\beta % \end{array} \right] % \, = \, % \left[ \begin{array}{c} v_1 \\ v_2 \\ v_3 \end{array} \right] % \] % Therefore, % \begin{eqnarray*} % \alpha & = & \arc\tan (v_1 / -v_2) \\ % \beta & = & \arc\tan (v_3 \sin\alpha / v_1) % \end{eqnarray*} % Unless $p_1=p_2=0$, in which case $\alpha=0$ and $\beta=\sign(p_3)90$, or % $p_1=p_3=0$, in which case $\beta=0$. % % The syntax of \verb+SetMatrixThreeD+ is % \[ % v_1\ v_2\ v_3\ \gamma\ \mathrm{SetMatrixThreeD} % \] % \verb+SetMatrixThreeD+ first computes % \[ % \begin{array}{ll} % a=\sin\alpha & b=\cos\alpha\\ % c=\sin\beta & d=\cos\beta\\ % e=\sin\gamma & f=\cos\gamma % \end{array} % \] % and then sets \verb+Matrix3D+ to \verb+[+$\tilde{x}$ $\tilde{z}$\verb+]+. % % \begin{macrocode} \pst@def{SetMatrixThreeD}<% dup sin /e ED cos /f ED /p3 ED /p2 ED /p1 ED p1 0 eq { /a 0 def /b p2 0 le { 1 } { -1 } ifelse def p3 p2 abs } { p2 0 eq { /a p1 0 lt { -1 } { 1 } ifelse def /b 0 def p3 p1 abs } { p1 dup mul p2 dup mul add sqrt dup p1 exch div /a ED p2 exch div neg /b ED p3 p1 a div } ifelse } ifelse atan dup sin /c ED cos /d ED /Matrix3D [ b f mul c a mul e mul sub a f mul c b mul e mul add d e mul b e mul neg c a mul f mul sub a e mul neg c b mul f mul add d f mul ] def> % \end{macrocode} % \end{macro} % % \begin{macro}{\tx@ProjThreeD} % The syntax of the macro \verb+tx@ProjThreeD+ is % \[ % x\ y\ z\ \mathrm{ProjThreeD}\ x'\ y' % \] % where $x'=\langle x, y, z\rangle \cdot \tilde{x}$ and $y'=\langle x, y, z\rangle \cdot % \tilde{z}$. % % \begin{macrocode} \pst@def{ProjThreeD}<% /z ED /y ED /x ED Matrix3D aload pop z mul exch y mul add exch x mul add 4 1 roll z mul exch y mul add exch x mul add exch> % \end{macrocode} % % To embed 2D $\langle x, y\rangle$ coordinates in 3D, the user specifies the normal % vector and an angle. If we decompose this normal vector into an angle, as % when converting 3D coordinates to 2D coordinates, and let $\hat\alpha$, % $\hat\beta$ and $\hat\gamma$ be the three angles, then when these angles are % all zero the coordinate $\langle x, y\rangle$ gets mapped to $\langle x, 0, y\rangle$, and % otherwise $\langle x, y\rangle$ gets mapped to % \[ % R_z(\hat\alpha) R_x(\hat\beta) R_y(\hat\gamma) % \left[ \begin{array}{c} x \\ 0 \\ y \end{array} \right] % \, = \, % \left[ \begin{array}{c} % \hat{x}_1 x + \hat{z}_1 y\\ % \hat{x}_2 x + \hat{z}_2 y\\ % \hat{x}_3 x + \hat{z}_3 y % \end{array} \right] % \] % where $\hat{x}$ and $\hat{z}$ are the first and third columns of $R_z(\hat\alpha) R_x(\hat\beta) R_y(\hat\gamma)$. % % Now add on a 3D-origin: % \[ % \left[ \begin{array}{c} % \hat{x}_1 x + \hat{z}_1 y + x_0\\ % \hat{x}_2 x + \hat{z}_2 y + y_0\\ % \hat{x}_3 x + \hat{z}_3 y + z_0 % \end{array} \right] % \] % % Now when we project back onto 2D coordinates, we get % \begin{align*} % x' & = \tilde{x}_1(\hat{x}_1 x + \hat{z}_1 y + x_0) + % \tilde{x}_2(\hat{x}_2 x + \hat{z}_2 y + y_0) + % \tilde{x}_3(\hat{x}_3 x + \hat{z}_3 y + z_0)\\ % & = % (\tilde{x}_1\hat{x}_1 + \tilde{x}_2\hat{x}_2 + \tilde{x}_3\hat{x}_3) x % + (\tilde{x}_1\hat{z}_1 + \tilde{x}_2\hat{z}_2 + \tilde{x}_3\hat{z}_3) y % + \tilde{x}_1 x_0 + \tilde{x}_2 y_0 + \tilde{z}_3 z_0\\ % y' & = \tilde{z}_1(\hat{x}_1 x + \hat{z}_1 y + x_0) + % \tilde{z}_2(\hat{x}_2 x + \hat{z}_2 y + y_0) + % \tilde{z}_3(\hat{x}_3 x + \hat{z}_3 y + z_0)\\ % & = % (\tilde{z}_1\hat{x}_1 + \tilde{z}_2\hat{x}_2 + \tilde{z}_3\hat{x}_3) x % + (\tilde{z}_1\hat{z}_1 + \tilde{z}_2\hat{z}_2 + \tilde{z}_3\hat{z}_3) y % + \tilde{z}_1 x_0 + \tilde{z}_2 y_0 + \tilde{z}_3 z_0 % \end{align*} % Hence, the transformation matrix is: % \[ % \left[ \begin{array}{c} % \tilde{x}_1\hat{x}_1 + \tilde{x}_2\hat{x}_2 + \tilde{x}_3\hat{x}_3) \\ % \tilde{z}_1\hat{x}_1 + \tilde{z}_2\hat{x}_2 + \tilde{z}_3\hat{x}_3) \\ % \tilde{x}_1\hat{z}_1 + \tilde{x}_2\hat{z}_2 + \tilde{x}_3\hat{z}_3) \\ % \tilde{z}_1\hat{z}_1 + \tilde{z}_2\hat{z}_2 + \tilde{z}_3\hat{z}_3) \\ % \tilde{x}_1 x_0 + \tilde{x}_2 y_0 + \tilde{z}_3 z_0 \\ % \tilde{z}_1 x_0 + \tilde{z}_2 y_0 + \tilde{z}_3 z_0 % \end{array} \right] % \] % \end{macro} % \begin{macro}{\tx@SetMatrixEmbed} % The syntax of \verb+SetMatrixEmbed+ is % \begin{align*} % x_0\ y_0\ z_0\ \hat{v_1}\ \hat{v_2}\ \hat{v_3}\ \hat{\gamma}\\ % v_1\ v_2\ v_3\ \gamma\ \mathrm{setMatrixEmbed} % \end{align*} % \verb+SetMatrixEmbed+ first sets \verb++ to the basis vectors for % the viewpoint projection (the tilde stuff above). Then it sets \verb+Matrix3D+ to % the basis vectors for the embedded plane. Finally, it sets the % transformation matrix to the matrix given above. % % \begin{macrocode} \pst@def{SetMatrixEmbed}<% \tx@SetMatrixThreeD Matrix3D aload pop /z3 ED /z2 ED /z1 ED /x3 ED /x2 ED /x1 ED \tx@SetMatrixThreeD [ Matrix3D aload pop z3 mul exch z2 mul add exch z1 mul add 4 1 roll z3 mul exch z2 mul add exch z1 mul add Matrix3D aload pop x3 mul exch x2 mul add exch x1 mul add 4 1 roll x3 mul exch x2 mul add exch x1 mul add 3 -1 roll 3 -1 roll 4 -1 roll 8 -3 roll 3 copy x3 mul exch x2 mul add exch x1 mul add 4 1 roll z3 mul exch z2 mul add exch z1 mul add ] concat> % \end{macrocode} % \end{macro} % % \subsection{Parameter} % % \begin{macro}{\psk@viewpoint} % First we need a macro \verb+\pssetzlength+ for the third coordinate. It is adopted from % the definition of the y-axes: % \begin{macrocode} \let\pssetzlength\pssetylength % \end{macrocode} % The viewpoint is set by its three coordinates $(x\ y\ z)$. It is preset % to $x=1$, $y=-1$ and $z=1$. % \begin{macrocode} \define@key[psset]{pst-3d}{viewpoint}{% \pst@expandafter\psset@@viewpoint#1 {} {} {} \@nil \let\psk@viewpoint\pst@tempg} \def\psset@@viewpoint#1 #2 #3 #4\@nil{% \begingroup \pssetxlength\pst@dima{#1}% \pssetylength\pst@dimb{#2}% \pssetzlength\pst@dimc{#3}% \xdef\pst@tempg{% \pst@number\pst@dima \pst@number\pst@dimb \pst@number\pst@dimc}% \endgroup} \psset[pst-3d]{viewpoint=1 -1 1} % \end{macrocode} % \end{macro} % % \begin{macro}{\psk@viewangle} % \begin{macrocode} \define@key[psset]{pst-3d}{viewangle}{% \pst@getangle{#1}\psk@viewangle} \psset[pst-3d]{viewangle=0} % \end{macrocode} % \end{macro} % % \begin{macro}{\psk@normal} % \begin{macrocode} \define@key[psset]{pst-3d}{normal}{% \pst@expandafter\psset@@viewpoint#1 {} {} {} \@nil \let\psk@normal\pst@tempg} \psset[pst-3d]{normal=0 0 1} % \end{macrocode} % \end{macro} % % \begin{macro}{\psk@embedangle} % \begin{macrocode} \define@key[psset]{pst-3d}{embedangle}{% \pst@getangle{#1}\psk@embedangle} \psset[pst-3d]{embedangle=0} % \end{macrocode} % \end{macro} % % \begin{macro}{\psTshadowsize} % \begin{macrocode} \define@key[psset]{pst-3d}{Tshadowsize}{% \pst@checknum{#1}\psTshadowsize} \psset[pst-3d]{Tshadowsize=1} % \end{macrocode} % \end{macro} % % \begin{macro}{\psk@Tshadowangle} % \begin{macrocode} \define@key[psset]{pst-3d}{Tshadowangle}{% \pst@getangle{#1}\psk@Tshadowangle} \psset[pst-3d]{Tshadowangle=60} % \end{macrocode} % \end{macro} % % \begin{macro}{\psTshadowcolor} % \begin{macrocode} \define@key[psset]{pst-3d}{Tshadowcolor}{% \pst@getcolor{#1}\psTshadowcolor} \psset[pst-3d]{Tshadowcolor=lightgray} % \end{macrocode} % \end{macro} % % \subsection{\texttt{PostScript} code} % % \begin{macro}{\tx@TMSave} % \begin{macrocode} \pst@def{TMSave}<% tx@Dict /TMatrix known not { /TMatrix { } def /RAngle { 0 } def } if /TMatrix [ TMatrix CM ] cvx def> % \end{macrocode} % \end{macro} % \begin{macro}{\tx@TMRestore} % \begin{macrocode} \pst@def{TMRestore}<% CP /TMatrix [ TMatrix setmatrix ] cvx def moveto> % % \end{macrocode} % \end{macro} % % \begin{macro}{\tx@TMChange} % The syntax: % \begin{verbatim} % {} TMChange % \end{verbatim} % \begin{macrocode} \pst@def{TMChange}<% \tx@TMSave /cp [ currentpoint ] cvx def % ??? Check this later. CM % \end{macrocode} % % Set ''standard`` coordinate system , with \verb+pt+ units and origin at currentpoint. % This let's us rotate, or whatever, around \TeX's current point, without % having to worry about strange coordinate systems that the dvi-to-ps % driver might be using. % \begin{macrocode} CP T \tx@STV % \end{macrocode} % Let M = old matrix (on stack), and M' equal current matrix. Then % go from M' to M by applying M Inv(M'). % \begin{macrocode} CM matrix invertmatrix % Inv(M') matrix concatmatrix % M Inv(M') % \end{macrocode} % Now modify transformation matrix: % \begin{macrocode} exch exec % \end{macrocode} % Now apply M Inv(M') % \begin{macrocode} concat cp moveto> % \end{macrocode} % \end{macro} % % \subsection{Three dimensional operations} % % There is only one macro which collects all the basic operations for three dimansional representation % of a text or graphic object. % % \begin{macro}{\ThreeDput} % \begin{macrocode} \def\ThreeDput{\def\pst@par{}\pst@object{ThreeDput}} \def\ThreeDput@i{\@ifnextchar({\ThreeDput@ii}{\ThreeDput@ii(\z@,\z@,\z@)}} \def\ThreeDput@ii(#1,#2,#3){% \pst@killglue\pst@makebox{\ThreeDput@iii(#1,#2,#3)}} \def\ThreeDput@iii(#1,#2,#3){% \begingroup \use@par \if@star\pst@starbox\fi \pst@makesmall\pst@hbox \pssetxlength\pst@dima{#1}% \pssetylength\pst@dimb{#2}% \pssetzlength\pst@dimc{#3}% \leavevmode \hbox{% \pst@Verb{% { \pst@number\pst@dima \pst@number\pst@dimb \pst@number\pst@dimc \psk@normal \psk@embedangle \psk@viewpoint \psk@viewangle \tx@SetMatrixEmbed } \tx@TMChange}% \box\pst@hbox \pst@Verb{\tx@TMRestore}}% \endgroup \ignorespaces} % \end{macrocode} % \end{macro} % % % \subsection{Arithmetic\label{Arithmetic}} % % \begin{macro}{\pst@sinandcos} % Syntax: % \begin{LVerbatim} % \pst@sinandcos{}{} % \end{LVerbatim} % , in "sp" units, should equal 100,000 times the angle, in degrees % between 0 and 90. should equal the angle's quadrant (0, 1, 2 or 3). % \verb+\pst@dimg+ is set to $\sin(\theta)$ and \verb+\pst@dimh+ is set to % $\cos(\theta)$ (in pt's). % % The algorithms uses the usual McLaurin expansion. % \begin{macrocode} \def\pst@sinandcos#1{% \begingroup \pst@dima=#1\relax \pst@dima=.366022\pst@dima %Now 1pt=1/32rad \pst@dimb=\pst@dima % dimb->32sin(angle) in pts \pst@dimc=32\p@ % dimc->32cos(angle) in pts \pst@dimtonum\pst@dima\pst@tempa \pst@cntb=\tw@ \pst@cntc=-\@ne \pst@cntg=32 \loop \ifnum\pst@dima>\@cclvi % 256 \pst@dima=\pst@tempa\pst@dima \divide\pst@dima\pst@cntg \divide\pst@dima\pst@cntb \ifodd\pst@cntb \advance\pst@dimb \pst@cntc\pst@dima \pst@cntc=-\pst@cntc \else \advance\pst@dimc by \pst@cntc\pst@dima \fi \advance\pst@cntb\@ne \repeat \divide\pst@dimb\pst@cntg \divide\pst@dimc\pst@cntg \global\pst@dimg\pst@dimb \global\pst@dimh\pst@dimc \endgroup} % \end{macrocode} % \end{macro} % % \begin{macro}{\pst@getsinandcos} % \verb+\pst@getsinandcos+ normalizes the angle to be in the first quadrant, sets % \verb+\pst@quadrant+ to 0 for the first quadrant, 1 for the second, 2 for the % third, and 3 for the fourth, invokes \verb+\pst@sinandcos+, and sets \verb+\pst@sin+ % to the sine and \verb+\pst@cos+ to the cosine. % \begin{macrocode} \def\pst@getsinandcos#1{% \pst@dimg=100000sp \pst@dimg=#1\pst@dimg \pst@dimh=36000000sp \pst@cntg=0 \loop \ifnum\pst@dimg<\z@ \advance\pst@dimg\pst@dimh \repeat \loop \ifnum\pst@dimg>\pst@dimh \advance\pst@dimg-\pst@dimh \repeat \pst@dimh=9000000sp \def\pst@tempg{% \ifnum\pst@dimg<\pst@dimh\else \advance\pst@dimg-\pst@dimh \advance\pst@cntg\@ne \ifnum\pst@cntg>\thr@@ \advance\pst@cntg-4 \fi \expandafter\pst@tempg \fi}% \pst@tempg \chardef\pst@quadrant\pst@cntg \ifdim\pst@dimg=\z@ \def\pst@sin{0}% \def\pst@cos{1}% \else \pst@sinandcos\pst@dimg \pst@dimtonum\pst@dimg\pst@sin \pst@dimtonum\pst@dimh\pst@cos \fi% } % \end{macrocode} % \end{macro} % % \subsection{Tilting} % % \begin{macro}{\pstilt} % \begin{macrocode} \def\pstilt#1{\pst@makebox{\pstilt@{#1}}} \def\pstilt@#1{% \begingroup \leavevmode \pst@getsinandcos{#1}% \hbox{% \ifcase\pst@quadrant \kern\pst@cos\dp\pst@hbox \pst@dima=\pst@cos\ht\pst@hbox \ht\pst@hbox=\pst@sin\ht\pst@hbox \dp\pst@hbox=\pst@sin\dp\pst@hbox \or \kern\pst@sin\ht\pst@hbox \pst@dima=\pst@sin\dp\pst@hbox \ht\pst@hbox=\pst@cos\ht\pst@hbox \dp\pst@hbox=\pst@cos\dp\pst@hbox \or \kern\pst@cos\ht\pst@hbox \pst@dima=\pst@sin\dp\pst@hbox \pst@dimg=\pst@sin\ht\pst@hbox \ht\pst@hbox=\pst@sin\dp\pst@hbox \dp\pst@hbox=\pst@dimg \or \kern\pst@sin\dp\pst@hbox \pst@dima=\pst@sin\ht\pst@hbox \pst@dimg=\pst@cos\ht\pst@hbox \ht\pst@hbox=\pst@cos\dp\pst@hbox \dp\pst@hbox=\pst@dimg \fi \pst@Verb{% { [ 1 0 \pst@cos\space \ifnum\pst@quadrant>\@ne neg \fi \pst@sin\space \ifnum\pst@quadrant>\z@\ifnum\pst@quadrant<\thr@@ neg \fi\fi \ifodd\pst@quadrant exch \fi 0 0 ] concat } \tx@TMChange}% \box\pst@hbox \pst@Verb{\tx@TMRestore}% \kern\pst@dima}% \endgroup} % \end{macrocode} % \end{macro} % % \begin{macro}{\psTilt} % \begin{macrocode} \def\psTilt#1{\pst@makebox{\psTilt@{#1}}} \def\psTilt@#1{% \begingroup \leavevmode \pst@getsinandcos{#1}% \hbox{% \ifodd\pst@quadrant \pst@@divide{\dp\pst@hbox}{\pst@cos\p@}% \ifnum\pst@quadrant=\thr@@\kern\else\pst@dima=\fi\pst@sin\pst@dimg \pst@@divide{\ht\pst@hbox}{\pst@cos\p@}% \ifnum\pst@quadrant=\@ne\kern\else\pst@dima=\fi\pst@sin\pst@dimg \else \ifdim\pst@sin\p@=\z@ \@pstrickserr{\string\psTilt\space angle cannot be 0 or 180}\@ehpa \def\pst@sin{.7071}% \def\pst@cos{.7071}% \fi \pst@@divide{\dp\pst@hbox}{\pst@sin\p@}% \ifnum\pst@quadrant=\z@\kern\else\pst@dima=\fi\pst@cos\pst@dimg \pst@@divide{\ht\pst@hbox}{\pst@sin\p@}% \ifnum\pst@quadrant=\tw@\kern\else\pst@dima=\fi\pst@cos\pst@dimg \fi \ifnum\pst@quadrant>\@ne \pst@dimg=\ht\pst@hbox \ht\pst@hbox=\dp\pst@hbox \dp\pst@hbox=\pst@dimg \fi \pst@Verb{% { [ 1 0 \pst@cos\space \pst@sin\space \ifodd\pst@quadrant exch \fi \tx@Div \ifnum\pst@quadrant>\z@\ifnum\pst@quadrant<\thr@@ neg \fi\fi \ifnum\pst@quadrant>\@ne -1 \else 1 \fi 0 0 ] concat } \tx@TMChange}% \box\pst@hbox \pst@Verb{\tx@TMRestore}% \kern\pst@dima}% \endgroup} % \end{macrocode} % \end{macro} % % % \subsection{Shadow} % % \begin{macro}{\psshadow} % \begin{macrocode} \def\psshadow{\pst@object{psshadow}} \def\psshadow@i{\pst@makebox{\psshadow@ii}} \def\psshadow@ii{% \begingroup \use@par \leavevmode \pst@getsinandcos{\psk@Tshadowangle}% \hbox{% \lower\dp\pst@hbox\hbox{% \pst@Verb{% { [ 1 0 \pst@cos\space \psTshadowsize mul \ifnum\pst@quadrant>\@ne neg \fi \pst@sin\space \psTshadowsize mul \ifnum\pst@quadrant>\z@\ifnum\pst@quadrant<\thr@@ neg \fi\fi \ifodd\pst@quadrant exch \fi 0 0 ] concat } \tx@TMChange}}% \hbox to\z@{% patch 2 (hv), to get it run with xcolor _and_ TeX \pst@Verb{ gsave \pst@usecolor\psTshadowcolor}% \copy\pst@hbox \pst@Verb{ grestore}\hss}% % \hbox to\z@{{\@nameuse{\psTshadowcolor}\copy\pst@hbox\hss}}% \pst@Verb{\tx@TMRestore}% \box\pst@hbox}% \endgroup} % \end{macrocode} % \end{macro} % % \subsection{Closing} % % Catcodes restoration. % % \begin{macrocode} \catcode`\@=\PstAtCode\relax % \end{macrocode} % % % \endinput %% %% END pst-3d.tex