Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like to define macros for functions defined on beams in structural mechanics course:

beams with forces and stresses

I am trying to cook up some macro which would draw each segment where the function is constant (perhaps later, where it is linear or similar). Ideally, they result would be used like this inside TikZ:

\beamFunc{AB={(0,0),(0,2)},func value=-500,label pos=.5,show label=true,show sign=false}; % this would be the first segment lower left

where the hatches are automatically perpendicular to (A)--(B). Below is my initial attempt, but I end with

! Incomplete \iffalse; all text was ignored after line 43.
<inserted text> 
                \fi 

without much idea about what is going on:

\documentclass{article}
\usepackage{tikz}
\begin{document}
   % define keys for the next command
   \pgfkeys{
      /prpe/beam/.cd,
      % endpoints of the beam (segment)
      AB/.value required,
      AB/.code n args={2}{
         \def\beamA{#1}
         \def\beamB{#2}
         \def\beamLen{\pgfmathparse{veclen($\beamB-\beamA$)}}
      },
      % constant function value along the beam (segment)
      func value/.value required,
      func value/.get=\beamF,
      % scaling of the function value to coordinates
      func scale/.get=\beamFuncScale,
      func scale/.initial=1.,
   }
   % define command for drawing the beam
   \newcommand{\prpeBeamConstFunc}[1]{
      \pgfkeys{/prpe/beam/.cd,#1}
      % find out how is the beam axis rotated
      \pgfmathanglebetweenpoints{(1,0)}{$\beamB-\beamA$};
      \let\beamAngle=\pgfmathresult
      % do the rest in beam-local coordinates
      \begin[rotate=\beamAngle,shift={\beamA}]{scope}
         % rectangle in local coordinates
         \coordinate (A) at (0,0);
         \coordinate (B) (\beamLen,0);
         \coordinate (Af) at (0,\beamFuncScale*\beamF);
         \coordinate (Bf) at (\beamLen,\beamFuncScale*\beamF);
         % beam itself
         \draw[thick] (A) -- (B);
         % hatched rectangle, with lines locally in the vertical direction
         \fill[pattern=north lines] (A)--(B)--(Bf)--(Af)--cycle;
      \end{scope}
   }
   % try it out here
   \begin{tikzpicture}   
      \prpeBeamConstFunc{AB={(0,0),(0,5)},func value=100,func scale=.01};
   \end{tikzpicture}
\end{document}

Can I get help in discovering the error? Since it is my first TikZ macro, any other suggestions are also welcome.

share|improve this question
add comment

1 Answer

Here is a basic decoration. It reads whether the beam to be drawn should be clamped or not. Then depending on the sign of the load magnitude it puts a + or - sign in the decoration and places the magnitude on top of it. You can change the clamped edge by drawing reverse but needs a little if clause to change the orientation of the label.

One thing that eludes me is that I can't give a line width option that only effect the beam and not the decoration. I tried some postaction magic but couldn't do it, it still leaks into the decoration. Also there is not much choice automation yet. The clamp hatching is rather sloppy etc. Please feel free to correct/improve this code.

I don't think it will be hard for you to customize this to get something concrete (hard to resist!).

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{patterns,decorations}
\newdimen\lohei
\newif\ifclamp
\pgfkeys{%
    /pgf/decoration/.cd,%
    load height/.code={\pgfmathsetlength\lohei{#1}},%
    loadmag/.code={\pgfmathparse{notless(#1,0) ? "$+$": "$-$"}\let\signtype=\pgfmathresult%
    \def\loadlabel{#1}},%
    clamped/.initial=false,
    clamped/.is if=clamp
    }

\pgfdeclaredecoration{beamloader}{initial}
{
    \state{initial}[width=0mm,next state=hatchedit]
    {
    \ifclamp
         \pgfmoveto{\pgfpoint{0}{-10mm}}
         \pgflineto{\pgfpoint{0}{10mm}}
         \foreach \x in {0,1,...,10}{
             \pgfmoveto{\pgfpoint{0}{\x mm}}
             \pgflineto{\pgfpointadd{\pgfpoint{0}{\x mm}}{\pgfpoint{-2mm}{-2mm}}}
             \pgfmoveto{\pgfpoint{0}{-\x mm}}
             \pgflineto{\pgfpointadd{\pgfpoint{0}{-\x mm}}{\pgfpoint{-2mm}{-2mm}}}
             \pgfmoveto{\pgfpointorigin}
         }
    \else \fi
    }
    \state{hatchedit}[width=2mm]
    {
        \pgfmoveto{\pgfpointorigin}
        \pgflineto{\pgfpoint{0cm}{\lohei}}
        \pgfmoveto{\pgfpointdecoratedinputsegmentlast}
    }
    \state{final}
    {
        \pgfpathrectanglecorners{\pgfpointdecoratedpathlast}{\pgfpoint{-\pgfdecoratedpathlength/1.0}{\lohei}}
        \pgfusepath{stroke}
        \pgftransformshift{\pgfpoint{-\pgfdecoratedpathlength/2}{.5\lohei+5}}
        \color{white}\pgfsetstrokecolor{black}
        \pgfset{inner sep=0}
        \pgfnode{circle}{north}{\color{black}\signtype}{node}{\pgfusepath{fill,stroke}}
        \color{red}
        %\pgftransformresetnontranslations
        \pgftext[bottom,at=\pgfpoint{0}{.5\lohei}]{\loadlabel N}
    }
}
\begin{document}


\begin{tikzpicture}
\draw [decorate,decoration={beamloader,clamped,load height=2cm,loadmag=500}] (-2cm,0) -- (-2cm,3cm);
\draw [decorate,decoration={beamloader,load height=0.6cm,loadmag=-100}] (-2cm,3cm) -- (-2cm,6cm) node[above] {kN};
\draw [decorate,decoration={beamloader,load height=0.5cm,loadmag=-275,clamped}] (5cm,2cm) -- (3cm,2cm);
\draw [decorate,decoration={beamloader,load height=0.5cm,loadmag=-275,clamped}] (0cm,0cm) -- (3cm,2cm);
\end{tikzpicture}

\end{document}

Beam Function output by TikZ

I also found out that if you start with a more general code, it is possible to get something easily for the arc shapes too.

Lastly, sorry for the weird loading numbers. I was just checking.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.