%% $Id: pst-vehicle.tex 376 2021-12-29 12:28:42Z herbert $ %% %% This is file `pst-vehicle.tex', %% %% IMPORTANT NOTICE: %% %% Package `pst-vehicle.tex' %% %% Thomas Söll %% with the collaboration of %% Juergen Gilg %% Manuel Luque %% Herbert Voß (bugfixes) %% %% This program can redistributed and/or modified under %% %% the terms of the LaTeX Project Public License %% %% Distributed from CTAN archives in directory %% %% macros/latex/base/lppl.txt; either version 1.3c of %% %% the License, or (at your option) any later version. %% %% %% DESCRIPTION: %% `pst-vehicle' is a PSTricks package %% %% \csname PSTvehicleLoaded\endcsname \let\PSTvehicleLoaded\endinput % Requires PSTricks, pst-xkey, pst-node packages \ifx\PSTricksLoaded\endinput\else\input pstricks.tex\fi \ifx\PSTXKeyLoaded\endinput\else\input pst-xkey.tex\fi \ifx\PSTplotLoaded\endinput\else\input pst-plot.tex\fi \ifx\PSTnodeLoaded\endinput\else\input pst-node.tex\fi \def\fileversion{1.3} \def\filedate{2021/12/29} \message{`PST' v\fileversion, \filedate} \edef\PstAtCode{\the\catcode`\@} \catcode`\@=11\relax \definecolor{greenSlp}{rgb}{0,0.4,0.0} \definecolor{redSlp}{rgb}{0.7,0.134,0.134} \pst@addfams{pst-vehicle} \define@key[psset]{pst-vehicle}{backwheel}[\wheelA]{\def\pst@backwheel{#1 }} % \define@key[psset]{pst-vehicle}{frontwheel}[\wheelA]{\def\pst@frontwheel{#1 }} % \define@key[psset]{pst-vehicle}{ownvehicle}{\def\pst@ownvehicle{#1 }} % \define@key[psset]{pst-vehicle}{vehicle}[\Bike]{\def\pst@vehicle{#1}} % \define@key[psset]{pst-vehicle}{GravNode}[]{\def\pst@GravNode{#1 }} % \define@key[psset]{pst-vehicle}{d}[5.8]{\def\pst@d{#1 }} % \define@key[psset]{pst-vehicle}{rF}[1.6]{\def\pst@rF{#1 }} % \define@key[psset]{pst-vehicle}{rB}[1.6]{\def\pst@rB{#1 }} % \define@key[psset]{pst-vehicle}{gang}[1]{\def\pst@gang{#1 }} % \define@key[psset]{pst-vehicle}{epsilon}[1e-6]{\def\pst@epsilon{#1 }} % \define@key[psset]{pst-vehicle}{startPos}[0]{\def\pst@startPos{#1 }} % \define@boolkey[psset]{pst-vehicle}[Pst@]{showSlope}[true]{} % \define@boolkey[psset]{pst-vehicle}[Pst@]{MonoAxis}[false]{} % %\define@boolkey[psset]{pst-vehicle}[Pst@]{EqValveStartPos}[true]{} % \input{pst-vehicle.data} \psset[pst-vehicle]{gang=1,epsilon=1e-6,rB=1.6,rF=1.6,d=5.8,vehicle=\Bike,ownvehicle=,backwheel=\wheelA,frontwheel=\wheelA,showSlope=true,% startPos=0,MonoAxis=false,GravNode=dA12 2 div 1} \psset{algebraic} \def\psVehicle{\def\pst@par{}\pst@object{psVehicle}}% \def\psVehicle@i#1#2#3{% \pst@killglue% \begingroup% \use@par %----------------------------------------------------------------------------------------------------- \expandafter\ifx\pst@vehicle\HighWheeler\psset{rF=4,rB=1.13,d=5.8}\fi \expandafter\ifx\pst@vehicle\Bike\psset{rF=1.6,rB=1.6,d=5.8}\fi \expandafter\ifx\pst@vehicle\Truck\psset{rF=1.9,rB=1.9,d=6.28}\fi \expandafter\ifx\pst@vehicle\Tractor\psset{rF=1,rB=1.4,d=4}\fi \expandafter\ifx\pst@vehicle\UniCycle\psset{rB=1.6,MonoAxis=true}\fi \expandafter\ifx\pst@vehicle\Segway\psset{MonoAxis=true}\fi \begin@SpecialObj \pst@Verb{% /rpn { tx@AlgToPs begin AlgToPs end cvx } def% /X0 #2 def % -------------- x-Wert des Punktes auf der Kurve, wo das Hinterrad die Kurve berührt; von diesem Wert startet die Rechnung /XST \pst@startPos\space def % Untergrenze für die Integration bei der Rotationswinkelbestimmung %---- % Definition of the function f(x), its first derivative f'(x) and \sqrt{1+f'(x)^2} Definition de la fonction et la premiere derivee /func (#3) rpn def /Diff (Derive(1,#3)) rpn def /DiffI (Derive(2,#3)) rpn def /dAB (sqrt(1+Diff^2)) rpn def /dABdiff (Derive(1,sqrt(1+(Derive(1,#3))^2))) rpn def /x XST def func /funcxST exch def %---- f(XST) /x XST def Diff /DiffxST exch def %---- f'(XST) /x X0 def func /funcX0 exch def % ----- f(X0) /x X0 def Diff /DiffX0 exch def % ----- f'(X0) /x X0 def DiffI /DiffIX0 exch def % --- f''(X0) %----------------------------------------------------------------------------------------------------------------------- /eps \pst@epsilon def % Definition of a transmission between frontwheel and backwheel (interesting for vehicles with pedals) --- Gangschaltung /Gang \pst@gang def %% Definition of a scaling factor for the vehicles #1 /skal exch def %------------------ Radius frontwheel ----------------------------------------- /rF \pst@rF def /rB \pst@rB def /dA12 \pst@d def /rFs rF skal mul def /rBs rB skal mul def %--------% dA12 = Distance between the axes of the wheels ----- Achsabstand --- distance entre les axes /dA12s dA12 skal mul def /tA 1 1 DiffX0 dup mul add sqrt div def% /deltaX0 tA DiffX0 mul rBs mul def /deltaY0 tA rBs mul def %----------------------------------------------------------------------------------------------------------------------------------------- /Function ((x-X0+rBs*DiffX0/(sqrt(1+(DiffX0)^2))-rFs*(Diff)/(sqrt(1+(Diff)^2)))^2+% (func-funcX0+rFs/(sqrt(1+(Diff)^2))-rBs/(sqrt(1+(DiffX0)^2)))^2-dA12s^2) rpn def %----------------------------------------------------------------------------------------------------------------------------------------- /FunctionST ((x-XST+rBs*DiffxST/(sqrt(1+(DiffxST)^2))-rFs*(Diff)/(sqrt(1+(Diff)^2)))^2+% (func-funcxST+rFs/(sqrt(1+(Diff)^2))-rBs/(sqrt(1+(DiffxST)^2)))^2-dA12s^2) rpn def %--------- inferior value to search for the intersection point of the frontwheel with the curve /Zeros { %% Funktion xinf 1 dict begin /Xinf exch def % ---------------------------------- Untergrenze für die Schnittpunktsuche des Vorderrades mit der Kurve % superior value to search for the intersection point of the frontwheel with the curve = X0 + distance axes + radius frontwheel + radius backwheel /Xsup Xinf dA12s add rBs rFs add add def % ---------- Obergrenze für die Schnittpunktsuche des Vorderrades mit der Kurve %---% Calculating the intersection point of the frontwheel with the function------ Schnittpunktberechnung --------------------------------- /NB 0 def %-----------------loop-variable ----- Laufvariable für loop /NbreIterations 200 def % ---------- Maximum of iterations for the loop { %------------------------------------ loop begin --------------------- /xM Xinf Xsup add 2 div def %--------- Mittelwert von xM = (Xinf + Xsup):2 /x Xinf def /F_1 FUNK def %----------------- F(Xinf) /x xM def %------------------------- /F_M FUNK def %----------------- F(xM) F_M 0 eq {exit} if %---------------- if F(xM) = 0 --> exit F_1 F_M mul 0 ge {/Xinf xM def} %-- F(Xinf) * F(xM) >= 0 Xinf = xM, else Xsup = xM {/Xsup xM def} ifelse Xinf Xsup sub abs 1e-8 le {exit} if %- if Xinf - Xsup <= 10^-8 --> exit /NB NB 1 add def %------------------- else loopvariable NB = NB + 1 Loopvariable um eins erhöhen NB NbreIterations ge {exit} if %------ if number of iterations >= 200 --> exit } loop xM end } def % \ifPst@EqValveStartPos /FUNK {FunctionST} def XST Zeros /FWxST exch def % \else /FWxST XST def \fi /FUNK {Function} def X0 Zeros /FWx exch def /FWy /x FWx def func def %----------------------- Berührpunkt des Vorderrades (FWx,FWy) /mFWy /x FWx def Diff def %----------------------- mFWy = Tangentensteigung in (FWx,FWy) /TermFW 1 1 mFWy dup mul add sqrt div def % 1/sqrt(1+f'(x_Q)^2) /deltaxFW TermFW mFWy mul rFs mul def % skal*rF*f'(x_Q)*1/sqrt(1+f'(x_Q)^2) /deltayFW TermFW rFs mul def % skal*rF*1/sqrt(1+f'(x_Q)^2) %------------------------------------------------------------------------------------ /KWRho {DiffI 1 Diff dup mul add 3 exp sqrt div} def /dPhiB {1 rBs div KWRho sub dAB mul abs} def /AngleCumB { % X1 X2 /x {dPhiB} eps SIMPSON } def /dPhiF {1 rFs div KWRho sub dAB mul abs} def /AngleCumF { % X1 X2 /x {dPhiF} eps SIMPSON } def % % length of the curve for the wheels -- La longueur de la courbe pour la roue avant --- Kurvenlänge /X1 XST def /X2 X0 def % Integral_{0}^{X0} /sB AngleCumB def % ---backwheel - length from 0 to X0 ---- roue arrière ---- Kurvenlänge von 0 bis X0 (Hinterrad) /X1 FWxST def /X2 FWx def /sF AngleCumF def % --frontwheel - length from 0 to the abscissa of the intersection frontwheel with curve - roue avant -- Kurvenlänge von 0 bis zum SP Vorderrad - Kurve %-------------------------------------------------------------------------------------------------------------------- %---% Definition angle of rotation for the backwheel --- Definition de l'angle de roue arriere ---- Rotationswinkel des Hinterrades /phiB sB RadToDeg neg def %---% Definition angle of rotation for the frontwheel --- Definition de l'angle de roue avant ---- Rotationswinkel des Vorderrades /phiF sF RadToDeg neg def %--------------------------------------------------------------------------------------------------------------------- %--% coordinates for the axes of the wheels within the non-scaled system -- Koordinaten der Vorderradachse im nicht skalierten System ( außerhalb der \psscalebox ) %---------------------------------------------------------------------------------------------------------------------- /AFx FWx deltaxFW sub def % % x-coordinate front axis x-Koordinate der Vorderradachse /AFy FWy deltayFW add def % % y-coordinate front axis y-Koordinate der Vorderradachse /ABx X0 deltaX0 sub def % % x-coordinate back axis x-Koordinate der Hinterradachse /ABy funcX0 deltaY0 add def % % y-coordinate back axis y-Koordinate der Hinterradachse %--------------- Koordinaten der Vorderradachse im System des Fahrzeugs, also unskalierte Größen verwenden --( innerhalb der \psscalebox ) %--coordinates for the front axis of the wheels within \psscalebox -- Die Koordinaten der Hinterradachse sind im System des Fahrzeugs (0,0) /AF1x dA12 dup mul rF rB sub dup mul sub sqrt def /AF1y rF rB sub def %------% slope and angle of the vehicle----------------------------------------------------------------------------- /m-vehicle AFy ABy sub AFx ABx sub div def /beta m-vehicle 1 atan def % % angle for both radii of front- and backwheel are equal -- Neigungswinkel des Fahrzeugs bei gleich großen Rädern /alpha AF1y neg AF1x atan def % % additional angle if radii of front- and backwheel are not equal -- zusätzlicher Winkel bei unterschiedlich großen Rädern % whole angle (correction with +180 in case the whole angle gets 90 degrees which can be possible with not equal radii) /gamma beta alpha add AFx ABx lt { 180 add } if def % gesamter Neigungswinkel des Fahrzeugs %--------% Special case (mono-axis vehicle) Nr 4 --> segway --------------------------------------------------------------------------- \ifPst@MonoAxis DiffX0 1 atan /omega exch def DiffX0 /mVehicle exch def \else FWy funcX0 sub FWx X0 sub div /mVehicle exch def mVehicle 1 atan /omega exch def \fi /normNorm FWy funcX0 eq { 1 } { X0 FWx sub FWy funcX0 sub div dup mul 1 add sqrt } ifelse def /mTgy FWy funcX0 eq { 1 } { X0 FWx sub FWy funcX0 sub div normNorm div } ifelse def /mTgx FWy funcX0 eq { 0 } { 1 normNorm div } ifelse def /xMTg X0 FWx add 2 div def /yMTg funcX0 FWy add 2 div def }% %------------------------%%%% END OF PS-CODE %%%%%-------------------------------------------------------- \pnode(!FWx FWy){FW}% % % angle between the axes angle de droite entre les axes \rput{!gamma}(!ABx ABy){% Das Fahrzeug wird mit Hilfe der Hinterradachse (ABx,ABy) und Gesamtdrehwinkel gamma gesetzt %------------------------- % SETTING SOME VEHICLES ------------------------------------------------------- \psscalebox{#1}{%---------------Das Fahrzeug kann skaliert werden ----------------------------------------- %\psset{linecolor=#2}% \pnode(!\pst@GravNode){GravC}% \pst@vehicle}}% \ifPst@showSlope \rput{!omega}(!X0 mVehicle 0 ge { 0 add } { 100 add } ifelse funcX0 0.75 sub){% \psframebox[fillstyle=solid,fillcolor=greenSlp,linestyle=none]{\footnotesize\color{white}$m\geq 0$}} \rput{!omega}(!X0 mVehicle 0 lt { 0 add } { 100 add } ifelse funcX0 0.75 sub){% \psframebox[fillstyle=solid,fillcolor=redSlp,linestyle=none]{\footnotesize\color{white}$m < 0$}} \ifPst@MonoAxis \psplotTangent[linewidth=0.75\pslinewidth,linecolor=orange,nodesep=-2]{X0}{1}{#3} \psplotTangent[linewidth=0.75\pslinewidth,linecolor=greenSlp,Tnormal,nodesep=-2]{X0}{1}{#3} \psdot[linecolor=red](!X0 funcX0) \else \pcline[linecolor=greenSlp,nodesepA=-1,nodesepB=-3](!xMTg yMTg)(!xMTg mTgy 0 ge { mTgx } { mTgx neg } ifelse add yMTg mTgy abs add) \pcline[linecolor=magenta,nodesep=-2](FW)(!X0 funcX0) \psdot[linecolor=red](FW) \psdot[linecolor=red](!X0 funcX0) \fi% \fi% \showpointsfalse \end@SpecialObj \endgroup\ignorespaces}% % \def\SlopeoMeter#1#2{% \colorlet{slpmColor}{#1} \rput{0}(0,0){% \pscircle[fillstyle=solid,fillcolor=black!90,linewidth=0.5pt,linestyle=solid](0,0){2.2} \rput{!#2}(0,0){% \multido{\r=.500+-.008,\rC=0+0.02}{25}{% \pscircle[linewidth=0.008,linecolor=slpmColor,strokeopacity=\rC](0,0){!\r} } \multido{\i=0+2,\r=.400+-.008,\rC=0+0.02}{50}{% \pswedge[linestyle=none,linewidth=0,fillstyle=solid,fillcolor=slpmColor,opacity=\r](0,0){2}{\i}{!\i\space 2 add} }} \multido{\nA=-90+10}{19}{% \psline[linecolor=slpmColor](1.8;\nA)(1.95;\nA) \rput(1.65;\nA){\psscalebox{0.4}{\color{slpmColor!10}\nA}} } \rput(-0.95,0.85){\psscalebox{0.6}{\color{slpmColor!20}\texttt{Steigungswinkel}}} \rput(-0.95,0.5){\psscalebox{0.75}{\color{slpmColor!40}\texttt{Slope-o-Meter}}} \rput{!#2}(0,0){% \pspolygon[fillstyle=solid,fillcolor=slpmColor!50,linecolor=slpmColor,linejoin=2,linewidth=0.1pt](0.1;15)(0.1;-15)(1.75;0) \pscircle[fillstyle=solid,fillcolor=black,linestyle=none,linewidth=0pt](0,0){0.3} }}} \catcode`\@=\PstAtCode\relax \endinput