%% %% Package `pst-pad.tex' %% %% Patrick Drechsler %% %% Version: $Id: pst-pad.tex 343 2008-08-19 21:05:10Z patrick $ %% %% %% DESCRIPTION: %% %% `pst-pad' is a PSTricks package to draw adhesion systems like %% Johnson-Kendall-Roberts (JKR) models, Hertz adhesion model and wet adhesion %% model. %% %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %%% TODO: %% %% PDTODO:A Implement "rough surfaces" %% %% PDTODO:A Create fluid contact angle option for Fluid. Not implemented yet. %% %% PDTODO:B Create options for surface combinations (basics of surface %% macros are present): %% %% - flat flat (ff): PstWall - PstWall %% %% - flat sphere (fs): PstWall - PstSphere %% %% - flat Fsphere (fp): PstWall - FSphere %% %% - surface rougness (roughness) %% %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% % ============================================================ \csname PSTpadLoaded\endcsname% \let\PSTpadLoaded\endinput% % %% Require PSTricks, pst-node, multido and pst-xkey packages: % \ifx\PSTMultidoLoaded\endinput\else\input multido.tex\fi% \ifx\PSTricksLoaded\endinput\else\input pstricks.tex\fi% \ifx\PSTnodeLoaded\endinput\else\input pst-node.tex\fi% \ifx\PSTXKeyLoaded\endinput\else\input pst-xkey \fi% % %% Define Version info: % \def\fileversion{0.3c}% \def\filedate{2008/08/19}% \message{`pst-pad' v\fileversion (pd)}% % % Allow to use the @ character for all internal macros \edef\PstAtCode{\the\catcode`\@}% \catcode`\@=11\relax% % %% Create new xkeyval family: % \pst@addfams{pst-pad}% % %% Not needed so far: % \pstheader{pst-pad.pro} % %% Activate special coordinates: % \SpecialCoor% % % ============================================================ % Key definitions: ============================================ % ============================================================ \define@key[psset]{pst-pad}{WallThickness}{\pst@getlength{#1}\Pst@WallThickness}% \define@key[psset]{pst-pad}{WallLineWidth}{\pst@getlength{#1}\Pst@WallLineWidth}% \define@key[psset]{pst-pad}{WallLineColor}{\pst@getcolor{#1}\Pst@WallLineColor}% \define@key[psset]{pst-pad}{WallString}{\def\psk@WallString{#1}}% \define@key[psset]{pst-pad}{WallAngle}{\pst@getangle{#1}\Pst@WallAngle}% %% \define@key[psset]{pst-pad}{SphereRadius}{\pst@getlength{#1}\Pst@SphereRadius}% \define@key[psset]{pst-pad}{SphereStartAngle}{\pst@getangle{#1}\Pst@SphereStartAngle}% \define@key[psset]{pst-pad}{SphereEndAngle}{\pst@getangle{#1}\Pst@SphereEndAngle}% \define@key[psset]{pst-pad}{SphereString}{\def\psk@SphereString{#1}}% \define@key[psset]{pst-pad}{SphereOffset}{\pst@getlength{#1}\Pst@SphereOffset}% \define@key[psset]{pst-pad}{SphereFillColor}{\pst@getcolor{#1}\Pst@SphereFillColor}% \define@key[psset]{pst-pad}{SphereLineWidth}{\pst@getlength{#1}\Pst@SphereLineWidth}% \define@key[psset]{pst-pad}{SphereLineColor}{\pst@getcolor{#1}\Pst@SphereLineColor}% %% \define@key[psset]{pst-pad}{FSphereHeight}{\pst@getlength{#1}\Pst@FSphereHeight}% \define@key[psset]{pst-pad}{FSphereFillColor}{\pst@getcolor{#1}\Pst@FSphereFillColor}% \define@key[psset]{pst-pad}{FSphereString}{\def\psk@FSphereString{#1}}% \define@key[psset]{pst-pad}{FSphereLineWidth}{\pst@getlength{#1}\Pst@FSphereLineWidth}% \define@key[psset]{pst-pad}{FSphereLineColor}{\pst@getcolor{#1}\Pst@FSphereLineColor}% %% \define@key[psset]{pst-pad}{FluidMaxRadius}{\pst@getlength{#1}\Pst@FluidMaxRadius}% \define@key[psset]{pst-pad}{FluidMinRadius}{\pst@getlength{#1}\Pst@FluidMinRadius}% \define@key[psset]{pst-pad}{FluidShearOffsetX}{\pst@getlength{#1}\Pst@FluidShearOffsetX}% \define@key[psset]{pst-pad}{FluidShearOffsetY}{\pst@getlength{#1}\Pst@FluidShearOffsetY}% \define@key[psset]{pst-pad}{FluidHeight}{\pst@getlength{#1}\Pst@FluidHeight}% \define@key[psset]{pst-pad}{FluidFillColor}{\pst@getcolor{#1}\Pst@FluidFillColor}% \define@key[psset]{pst-pad}{FluidString}{\def\psk@FluidString{#1}}% \define@key[psset]{pst-pad}{FluidLineWidth}{\pst@getlength{#1}\Pst@FluidLineWidth}% \define@key[psset]{pst-pad}{FluidLineColor}{\pst@getcolor{#1}\Pst@FluidLineColor}% %% \define@key[psset]{pst-pad}{StringA}{\def\psk@StringA{#1}}% \define@key[psset]{pst-pad}{StringB}{\def\psk@StringB{#1}}% %% \define@key[psset]{pst-pad}{TotalAngle}{\pst@getangle{#1}\Pst@TotalAngle}% %% %% TODO: Change this variables from dim to number: \define@key[psset]{pst-pad}{RoughnessMax}{\pst@getlength{#1}\Pst@RoughnessMax}% \define@key[psset]{pst-pad}{RoughnessWidth}{\pst@getlength{#1}\Pst@RoughnessWidth}% %% \define@boolkey[psset]{pst-pad}[Pst@]{fluid}[true]{}% %% \define@boolkey[psset]{pst-pad}[Pst@]{rough}[true]{}% \define@boolkey[psset]{pst-pad}[Pst@]{roughA}[true]{}% \define@boolkey[psset]{pst-pad}[Pst@]{roughB}[true]{}% %% I might need something like this for defining different surfaces. %% %% Adapted From pst-labo.tex : %% %% 0->PAD 1->WALL 2->SPHERE % \def\pst@@PAD{pad} % \def\pst@@WALL{wall} % \def\pst@@SPHERE{sphere} % % % \define@key[psset]{pst-pad}{surfaceType}{% % \def\pst@tempA{#1} % \edef\psk@surfaceType{% % \ifx\pst@@PAD\pst@tempA 0 \else % \ifx\pst@@WALL\pst@tempA 1 \else % \ifx\pst@@SPHERE\pst@tempA 2 \else 0 % \typeout{pst-pad: unknown surfaceType -> #1} % \typeout{ using type "pad" instead.} % \fi\fi\fi\fi% % default is pad % }} % ============================================================ % Default psset values: ======================================= % ============================================================ \psset[pst-pad]{% fluid=true, rough=false, roughA=false, roughB=false,% % WallThickness=1,WallString={},WallAngle=0,WallLineWidth=1pt,WallLineColor=black,% %% SphereStartAngle=180,SphereEndAngle=360,SphereRadius=1,SphereString={},% SphereOffset=0,SphereFillColor=white,SphereLineWidth=1pt,SphereLineColor=black,% %% FSphereHeight=2,FSphereFillColor=lightgray,FSphereString={},FSphereLineWidth=1pt,% FSphereLineColor=black,% %% FluidMaxRadius=1,FluidMinRadius=.5,FluidHeight=.5,% FluidFillColor=yellow,FluidString={},% FluidShearOffsetX=0,FluidShearOffsetY=0,FluidLineWidth=1pt,% FluidLineColor=black,% %% RoughnessMax=0, RoughnessWidth=0,% %% StringA={},StringB={},TotalAngle=0} % % %% Redefine RoughnessMax and RoughnessWidth: % \def\Pst@Rm{\Pst@RoughnessMax\space 0.5 mul }% % %% testing: % \def\Rw{\Pst@RoughnessWidth\space \Pst@RoughnessMax }% % ============================================================ % PstFluid ==================================================== % ============================================================ \def\PstFluid{\@ifnextchar[{\pst@PstFluid@i}{\pst@PstFluid@i[]}}% \def\pst@PstFluid@i[#1](#2){{% \psset{#1}% \begin@ClosedObj% \rput{\Pst@WallAngle}(#2){% %% Nodes (currently not used; They can be used outside of the macro as %% referece points): %% Fbr (Fluid bottom right): \pnode(! \Pst@FluidMaxRadius \Pst@FluidShearOffsetX sub \Pst@FluidHeight neg){Fbr}% %% Fbl (Fluid bottom left): \pnode(! \Pst@FluidMaxRadius \Pst@FluidShearOffsetX add neg \Pst@FluidHeight neg){Fbl}% %% Ftl (Fluid top left): \pnode(! \Pst@FluidMaxRadius neg \Pst@FluidShearOffsetX add \Pst@FluidHeight){Ftl}% %% Ftr (Fluid top right): \pnode(! \Pst@FluidMaxRadius \Pst@FluidShearOffsetX add \Pst@FluidHeight){Ftr}% %% %% \pscustom[linewidth=\Pst@FluidLineWidth,linecolor=\Pst@FluidLineColor,unit=1pt]{% %% Left meniscus: \pscurve% (! \Pst@FluidMaxRadius neg \Pst@FluidShearOffsetX add \Pst@FluidHeight)% (! \Pst@FluidMinRadius neg 0 \Pst@FluidShearOffsetY add)% (! \Pst@FluidMaxRadius \Pst@FluidShearOffsetX add neg \Pst@FluidHeight neg)% %% Bottom line: \psline% (! \Pst@FluidMaxRadius \Pst@FluidShearOffsetX add neg \Pst@FluidHeight neg)% (! \Pst@FluidMaxRadius \Pst@FluidShearOffsetX sub \Pst@FluidHeight neg)% %% %% PDTODO:A Fix ZigZag and Curved line: %% %% Bottom line with zigzag: % \multido{\rX=-\Pst@FluidMaxRadius+10}{5}{% % \multido{\rX=-\Pst@FluidMaxRadius+10}{! \Pst@FluidMaxRadius 2 mul 10 div floor}{% % \psline(\rX,-\Pst@FluidHeight)% % (! \rX\space 2.5 add \Pst@FluidHeight neg 5 add)% % (! \rX\space 7.5 add \Pst@FluidHeight neg 5 sub)% % (! \rX\space 10 add \Pst@FluidHeight neg)% % } %% Bottom line with curve: % \multido{\rX=-\Pst@FluidMaxRadius+10}{5}{% % \pscurve(\rX,-\Pst@FluidHeight)% % (! \rX\space 2.5 add \Pst@FluidHeight neg 5 add)% % (! \rX\space 7.5 add \Pst@FluidHeight neg 5 sub)% % (! \rX\space 10 add \Pst@FluidHeight neg)% % } %% Right meniscus: \pscurve[liftpen=1]% (! \Pst@FluidMaxRadius \Pst@FluidShearOffsetX sub \Pst@FluidHeight neg)% (! \Pst@FluidMinRadius 0 \Pst@FluidShearOffsetY sub)% (! \Pst@FluidMaxRadius \Pst@FluidShearOffsetX add \Pst@FluidHeight)% %% Top line: \psline% (! \Pst@FluidMaxRadius \Pst@FluidShearOffsetX add \Pst@FluidHeight)% (! \Pst@FluidMaxRadius neg \Pst@FluidShearOffsetX add \Pst@FluidHeight)% %% Fill: \fill[fillstyle=solid,fillcolor=\Pst@FluidFillColor]% }% %% String placement if String is present: \ifx\psk@FluidString\@empty\else% \rput[C]{-\Pst@TotalAngle}(0,0){\psk@FluidString}% \fi}% \end@ClosedObj% }\ignorespaces}% % ============================================================ % PstWall ===================================================== % ============================================================ \def\PstWall{\pst@object{PstWall}}% \def\PstWall@i(#1){{% \pst@killglue% \addbefore@par{linewidth=2pt}% \use@par% \rput{\Pst@WallAngle}(#1){% \psset{unit=1pt,linewidth=\Pst@WallLineWidth,linecolor=\Pst@WallLineColor,dimen=middle}% %% Main rectangle frame: \psframe[linestyle=none,fillstyle=hlines]% (! \Pst@FluidMaxRadius 10 add neg \Pst@WallThickness neg)% (! \Pst@FluidMaxRadius 10 add 0)% %% Extra line for "surface": \psline% (! \Pst@FluidMaxRadius 10 add neg 0)% (! \Pst@FluidMaxRadius 10 add 0)% %% String placement if string is present: \ifx\psk@WallString\@empty\else% \rput*[C]{\Pst@WallAngle}% pdtodo: fix this % \rput*[C]{! \Pst@TotalAngle \Pst@WallAngle sub}% (! -\Pst@WallThickness .5 mul 0 exch){\psk@WallString}% \fi}% }\ignorespaces}% % ============================================================ % PstWallRough ================================================ % ============================================================ %% %% PDTODO:A This macro is not implemented yet. %% \def\PstWallRough{\pst@object{PstWallRough}}% \def\PstWallRough@i(#1){{% \pst@killglue \addbefore@par{linewidth=1pt}% \use@par% \rput{\Pst@WallAngle}(#1){% \psset{unit=1pt,linewidth=\Pst@WallLineWidth,dimen=middle}% %% % \def\maxtmp{!\Pst@FluidMaxRadius\space 2 diff } \psframe[fillstyle=solid,fillcolor=gray]% (-\Pst@FluidMaxRadius,-\Pst@WallThickness)(\Pst@FluidMaxRadius,-\Pst@RoughnessMax)% % (! \maxtmp \Pst@WallThickness neg)(\Pst@FluidMaxRadius,-\Pst@RoughnessMax) %% \pscustom{% %% TODO:C Replace algebraic with RPN notation: \psplot[plotpoints=100,algebraic=true]{-\Pst@FluidMaxRadius}{\Pst@FluidMaxRadius}% {\Pst@RoughnessMax*sin(x*Pi*\Pst@RoughnessWidth-(Pi/2))}% % \psplot[plotpoints=100]{-\Pst@FluidMaxRadius}{\Pst@FluidMaxRadius}% % %% TODO:A Ignore pt units for this numeric test and use the original % %% input number!!!!: % {\Pst@RoughnessWidth round 2 mod 0 eq % <- IF CONDITION % {/MyFac \Pst@RoughnessWidth round 1 add def }% IF == TRUE STATEMENT % {/MyFac \Pst@RoughnessWidth round 2 div floor def } % <- ELSE STATEMENT % ifelse % <- END IF-ELSE % x \Pst@FluidMaxRadius round div MyFac mul 180 mul sin% % }% end psplot \gsave% \psline(\Pst@FluidMaxRadius,-\Pst@RoughnessMax)(-\Pst@FluidMaxRadius,-\Pst@RoughnessMax)% \fill[fillcolor=gray,fillstyle=solid]% \grestore% }% %% String placement if String is present: \ifx\psk@WallString\@empty\else% \rput*[C]{\Pst@WallAngle}% pdtodo: fix this % \rput*[C]{! \Pst@TotalAngle \Pst@WallAngle sub}% (! -\Pst@WallThickness .5 mul 0 exch){\psk@WallString}% \fi% }% }\ignorespaces}% % ============================================================ % PstSphere ===================================================== % ============================================================ \def\PstSphere{\pst@object{PstSphere}}% \def\PstSphere@i(#1){{% \pst@killglue \addbefore@par{linewidth=1pt}% \use@par% \rput(#1){% \psset{unit=1pt,linewidth=\Pst@SphereLineWidth,linecolor=\Pst@SphereLineColor,dimen=middle}% %% Draw the "sphere" using the psarc macro: \psarc[fillstyle=solid,fillcolor=\Pst@SphereFillColor]% (0,\Pst@SphereRadius){\Pst@SphereRadius}% {\Pst@SphereStartAngle}{\Pst@SphereEndAngle}% %% Display string if present: \ifx\psk@SphereString\@empty\else% \rput[C]{\Pst@TotalAngle}% (! \Pst@SphereRadius .5 mul \pst@number\pslinewidth add 0 exch)% {\psk@SphereString}% \fi}% }\ignorespaces}% % ============================================================ % PstFlattenedSphere ========================================== % ============================================================ \def\PstFlattenedSphere{\pst@object{PstFlattenedSphere}}% \def\PstFlattenedSphere@i(#1){{% \pst@killglue \addbefore@par{linewidth=1pt}% \use@par% \rput(#1){% \psset{unit=1pt,linewidth=\Pst@FSphereLineWidth,linecolor=\Pst@FSphereLineColor,dimen=middle}% %% The "flattened sphere" is drawn as a rectangle frame with rounded %% corners (arc). It is then overlayed and clipped by a rectangle half %% the height to produce the look of a flattened sphere. \begin{psclip}{% \psframe[linestyle=none]% (!\Pst@FSphereHeight .5 mul \Pst@FluidMaxRadius add neg 0)% (!\Pst@FSphereHeight .5 mul \Pst@FluidMaxRadius add \Pst@FSphereHeight .5 mul)% }% \psframe[framearc=2,fillstyle=solid,fillcolor=\Pst@FSphereFillColor]% (!\Pst@FluidMaxRadius neg \Pst@FSphereHeight .5 mul sub 0)% (!\Pst@FluidMaxRadius \Pst@FSphereHeight .5 mul add \Pst@FSphereHeight)% \end{psclip}% %% Display string if present: \ifx\psk@FSphereString\@empty\else% \rput[C]{-\Pst@TotalAngle}(! \Pst@FSphereHeight .3 mul 0 exch){\psk@FSphereString}% \fi}% }\ignorespaces}% % ============================================================ % PstPad ====================================================== % ============================================================ \def\PstPad{\pst@object{PstPad}}% \def\PstPad@i(#1){{% \pst@killglue% \addbefore@par{linewidth=1pt}% \use@par% \rput{\Pst@TotalAngle}(#1){% \psset{unit=1pt}% %% Test for fluid true/false: \ifPst@fluid% %%fluid = true: \PstFluid(0,0)% \PstFlattenedSphere[FSphereString=\psk@StringA]% (! 0 \Pst@FluidShearOffsetX add \Pst@FluidHeight)% %% Test if WallString is empty: \ifx\psk@WallString\@empty% \PstWall% (! 0 \Pst@FluidShearOffsetX sub \Pst@FluidHeight neg)% \else% \PstWall[WallString=\psk@WallString]% (! 0 \Pst@FluidShearOffsetX sub \Pst@FluidHeight neg)% \fi% \else% %%fluid = false: \PstFlattenedSphere(0,0)% \PstWall(0,0)% \fi% }% }\ignorespaces}% % ============================================================ % WallToWall ================================================== % ============================================================ \def\PstWallToWall{\pst@object{PstWallToWall}}% \def\PstWallToWall@i(#1){{% \pst@killglue% \addbefore@par{linewidth=4pt}% \use@par% \rput{\Pst@TotalAngle}(#1){% \psset{unit=1pt}% \PstFluid(0,0)% %% Test if StringA is empty: \ifx\psk@StringA\@empty% \PstWall[WallAngle=180]% (! 0 \Pst@FluidShearOffsetX add \Pst@FluidHeight)% \else% \PstWall[WallAngle=180,WallString=\psk@StringA]% (! 0 \Pst@FluidShearOffsetX add \Pst@FluidHeight)% \fi% %% Test if StringB is empty: \ifx\psk@StringB\@empty% \PstWall% (! 0 \Pst@FluidShearOffsetX sub \Pst@FluidHeight neg)% \else% \PstWall[WallString=\psk@StringB]% (! 0 \Pst@FluidShearOffsetX sub \Pst@FluidHeight neg)% \fi% }% }\ignorespaces}% % ============================================================ % SphereToWall ================================================ % ============================================================ %% %% PDTODO:A I would like this macro to have "fluid = false" as the default %% value (all other major macros need "fluid = true" as default values). \def\PstSphereToWall{\pst@object{PstSphereToWall}}% \def\PstSphereToWall@i(#1){{% \pst@killglue% \addbefore@par{linewidth=1pt}% \use@par% \rput{\Pst@TotalAngle}(#1){% \psset{unit=1pt}% %% Test for fluid true/false: \ifPst@fluid% fluid = true: \PstFluid(0,0)% <- display fluid macro \PstSphere[SphereString=\psk@StringA]% (! 0 \Pst@FluidShearOffsetX add \Pst@FluidHeight)% %% Test if StringB is empty: \ifx\psk@StringB\@empty% \PstWall[fillstyle=none]% <- display wall macro (! 0 \Pst@FluidShearOffsetX sub \Pst@FluidHeight neg)% \else% \PstWall[fillstyle=none,WallString=\psk@StringB]% <- display wall macro (! 0 \Pst@FluidShearOffsetX sub \Pst@FluidHeight neg)% \fi% \else% fluid = false: \PstWall[linewidth=1pt,fillstyle=none,WallString=\psk@StringB](0,0)% <- display wall macro \PstSphere[SphereString=\psk@StringA](0,-\Pst@SphereOffset)% <- display sphere macro \psline[linewidth=0.8pt,linestyle=dashed,linecolor=gray]% (-\Pst@FluidMaxRadius,0)(\Pst@FluidMaxRadius,0)% \PstWall[linewidth=1pt,fillstyle=none](0,0)% <- display wall macro % \PstWallRough[unit=1cm](0,\Pst@RoughnessMax)% \fi% }% }\ignorespaces}%