%% $Id: pst-massspring.tex 1191 2025-12-18 09:53:56Z herbert $
%%
%% Package `pst-massspring.tex'
%%
%% Manuel Luque <manuel.luque27@gmail.com>
%% Herbert Voss <hvoss@tug.org>
%%
%% This program can be redistributed and/or modified under the terms
%% of the LaTeX Project Public License Distributed from CTAN archives
%% in directory macros/latex/base/lppl.txt.
%%
%% DESCRIPTION:
%%   `pst-massspring' is a PSTricks package to 
%%   create the free fall of two masses connected by a spring


\csname PSTmassspringLoaded\endcsname
\let\PSTmassspringLoaded\endinput

\ifx\PSTricksLoaded\endinput\else\input pstricks.tex\fi
\ifx\PSTXKeyLoaded\endinput\else \input pst-xkey.tex \fi
\ifx\PstSlopeLoaded\endinput\else \input pst-slpe.tex \fi

\def\fileversion{0.01}
\def\filedate{2025/12/18}

\message{ v\fileversion, \filedate}

\edef\PstAtCode{\the\catcode`\@} \catcode`\@=11\relax
\pst@addfams{pst-massspring}

\define@key[psset]{pst-massspring}{N}[10]{\def\psk@NbreSpires{#1 }}
% rayon initial du ressort (à vide) en cm
\define@key[psset]{pst-massspring}{R}[1]{\def\psk@RayonInitial{#1 }}
% longueur initiale du ressort (à vide)
\define@key[psset]{pst-massspring}{li}[10]{\def\psk@LongueurInitiale{#1 }}
% projection en perspective donnée par l'angle alpha
\define@key[psset]{pst-massspring}{alpha}[15]{\def\psk@Alpha{#1 }}
% longueur de l'attache à chaque extrémité du ressort en cm
\define@key[psset]{pst-massspring}{dl}[0]{\def\psk@dl{#1 }}
% nombre de points par spires
\define@key[psset]{pst-massspring}{nS}[25]{\def\psk@nS{#1 }}
\psset[pst-massspring]{N=10,R=0.5,alpha=15,dl=0,li=5,nS=25}
%
\def\psSpiral{\def\pst@par{}\pst@object{psSpiral}}
\def\psSpiral@i{\pst@getarrows\psSpiral@ii}
\def\psSpiral@ii(#1){\@ifnextchar({\psSpiral@iii{1}(#1)}{\psSpiral@iii{\z@}(0,0)(#1)}}
\def\psSpiral@iii#1(#2)(#3){%
  \begin@OpenObj
  \pst@getcoor{#2}\pst@tempa
  \pst@getcoor{#3}\pst@tempb
  \addto@pscode{
    \pst@tempa \pst@tempb
    /y1 ED /x1 ED /y0 ED /x0 ED
     x0 y0 translate
     y1 y0 sub x1 x0 sub 2 copy Pyth
    /Longueur ED
     Atan rotate
    /NbreSpires \psk@NbreSpires def % nombre de spires
    /Alpha \psk@Alpha def
    /R_0 \psk@RayonInitial \pst@number\psunit mul def
    /dl \psk@dl \pst@number\psunit mul def
    /l_0 \psk@LongueurInitiale \pst@number\psunit mul def
    /nS \psk@nS def
    /Pas_0 l_0 NbreSpires div def
    /Pas Longueur 2 dl mul sub NbreSpires div def
    % longueur de l'hélice sur un tour
    % = sqrt(4*pi^2*R^2+p^2)
    /Longueur_Helice_pas 39.47842 R_0 dup mul mul Pas_0 dup mul add sqrt def
    % R=1/(2*pi)*sqrt(L^2-p^2)
    /Radius 0.1591549 Longueur_Helice_pas dup mul Pas dup mul sub sqrt mul def
    /xH {Radius 360 t mul cos mul Radius sub} def
    /yH {Radius 360 t mul sin mul} def
    /zH {Pas t mul dl add} def
    /Inc 1 NbreSpires nS mul div def % nS(50) points par spires
     1 setlinejoin
      1 0 0 0 ArrowA dl 0 lineto
     0 Inc NbreSpires {/t ED
     zH xH Alpha tan mul sub
     yH
     lineto
        } for
     Longueur 0
      ArrowB lineto
      }%
  \end@OpenObj}

%% Two masses and a spring

\define@key[psset]{pst-massspring}{m1}{\def\pst@spring@mA{#1 }} % masse 1 (kg)
\define@key[psset]{pst-massspring}{m2}{\def\pst@spring@mB{#1 }} % masse 2 (kg)
\define@key[psset]{pst-massspring}{k}{\def\pst@spring@k{#1 }}   % constante de raideur N/m
\define@key[psset]{pst-massspring}{l0}{\def\pst@spring@L{#1 }}  % longueur initiale du spiralressort en cm
\define@key[psset]{pst-massspring}{t}{\def\pst@spring@t{#1 }}   % temps (s)
\psset[pst-massspring]{m1=0.5,m2=2,t=0,k=7.5,l0=5}%

\definecolor{woodcolor}{rgb}{0.95 0.84 0.5}

\def\psElectromagnet{%
  % l'aimant
  \psframe*[linecolor={[rgb]{0 0 0.5}}](-0.2,0)(0.2,2)
  \psframe[fillstyle=solid,fillcolor=white](-0.4,0.2)(0.4,1.8)
  \psframe[fillstyle=hlines,hatchangle=0,hatchsep=0.1](-0.4,0.2)(0.4,1.8)
  % l'interrupteur à couteau
  \psframe[fillstyle=solid,fillcolor=woodcolor](1.75,0.2)(3.75,0.5)
  % le couteau
  \ifdim\pst@spring@t pt=\z@
    \rput(2,0.75){
      \psframe[framearc=0.1,fillstyle=solid,fillcolor=orange!50](0,-0.05)(1.65,0.05)
      \psframe[framearc=0.5,fillstyle=solid,fillcolor=black](1.55,-0.1)(1.95,0.1)%
    }%
    \pscustom[fillstyle=solid,fillcolor=red!20]{\psarc(2,0.8){0.1}{0}{180}\psline(1.9,0.5)(2.1,0.5)\closepath}
  \else
    \rput{60}(2,0.75){%
      \psframe[framearc=0.1,fillstyle=solid,fillcolor=orange!50](0,-0.05)(1.65,0.05)
      \psframe[framearc=0.5,fillstyle=solid,fillcolor=black](1.55,-0.1)(1.95,0.1)
    }%
    \pscustom[fillstyle=solid,fillcolor=red!20]{\psarc(2,0.8){0.1}{0}{180}\psline(1.9,0.5)(2.1,0.5)\closepath}
  \fi
  \psdot(2,0.75)
  \psframe[fillstyle=solid,fillcolor=red!20](3.2,0.5)(3.4,0.9)
  \psline[linearc=0.05](0.4,0.25)(0.6,0.25)(0.6,0.1)(3.3,0.1)(3.3,0.6)
  \psdot[dotsize=0.075](3.3,0.6)
  % battery
  \psframe[fillstyle=solid,fillcolor=blue!20](0.8,1.1)(1.55,1.65)
  \psframe*[linecolor=red](0.9,1.65)(1,1.75)
  \psframe*(1.35,1.65)(1.45,1.75)
  \psline(0.4,1.7)(0.9,1.7)
  \psdot[dotsize=0.075](3.3,0.6)
  \psline[linearc=0.05](1.4,1.7)(1.8,1.7)(1.8,0.55)(2,0.55)
  \psdot[dotsize=0.075](2,0.55)
  \rput(1.225,1.4){\footnotesize6V}%
}%
  %
\def\psMassSpring{\def\pst@par{}\pst@object{ps@MassSpring}}
\def\ps@MassSpring@i{%
  \begin@SpecialObj
%    \addto@pscode{
  \pstVerb{
    /m1 \pst@spring@mA def
    /m2 \pst@spring@mB def
    /radius1 m1 1 3 div exp def /radius2 m2 1 3 div exp def
    /kR \pst@spring@k def
    /l0 \pst@spring@L def
    /Gravity 9.81 def
    /mu m1 m2 mul m1 m2 add div def
    /w0 kR mu div sqrt 180 mul 6.283185 div def % pulsation in degrees
%    /T0 6.283185 kR mu div sqrt div def % period
    /t@ \pst@spring@t def
    /z20 radius1 radius2 add l0 add m2 Gravity mul kR div add def
    /Z@ m2 Gravity mul kR div
          t@ w0 mul cos mul l0 add radius1 add radius2 add def
    /zG0 m2 z20 mul m1 m2 add div def
    /zG 0.5 Gravity mul t@ 2 exp mul zG0 add def
    /z1 zG m2 m1 m2 add div Z@ mul sub def
    /z2 Z@ z1 add def
    /zR1 z1 neg radius1 sub def
    /zR2 z2 neg radius2 add def
  }%
  \psset{dimen=middle}
  \pscircle[style=BillesA](! 0 z1 neg){! radius1}
  \pscircle[style=BillesA](! 0 z2 neg){! radius2}
  \rput(! 0 radius1 2.5 add){t=\pst@spring@t{}s}
  \psSpiral[R=0.4,N=15]{-}(!0 zR1)(!0 zR2)
  \pscircle[style=BilleR](! 2 z20 0.5 Gravity mul t@ dup mul mul add neg){0.25}
  \pscircle[style=BilleB](! 2 0.5 Gravity mul t@ dup mul mul neg){0.25}
  \psdot(!0 zG neg)
  \psframe*(! -5.5 z20 radius2 1.5 mul add neg)(-2.5,2)
  \rput(! -4 zG0 neg){%
    \pscircle[style=BillesB](! 0 z1 zG sub neg){! radius1}
    \pscircle[style=BillesB](! 0 z2 zG sub neg){! radius2}
    \psSpiral[linecolor=white,R=0.4,N=15]{-}(! 0 zR1 zG add)(! 0 zR2 zG add )
    \psdot[linecolor=red](0,0)
  }
  \rput(!0 radius1){\psElectromagnet}
  \end@SpecialObj
  \ignorespaces
}
%
\newpsstyle{BillesA}{fillstyle=ccslope,slopebegin=white,slopeend=black,slopecenter=0.7 0.7}
\newpsstyle{BillesB}{fillstyle=ccslope,slopebegin=black,slopeend=white,slopecenter=0.7 0.7,linecolor=white,linestyle=none}
\newpsstyle{BilleR}{fillstyle=ccslope,slopebegin=white,slopeend=red,slopecenter=0.1 0.1,linecolor=red}
\newpsstyle{BilleB}{fillstyle=ccslope,slopebegin=white,slopeend=blue,slopecenter=0.1 0.1,linecolor=blue}

\catcode`\@=\PstAtCode\relax
\endinput
