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'm trying to reproduce in like the following picture:

Actually I would like to slightly modifies it as I would like all the spring to be connected to a common wall at the top. I have begin it with the following code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{patterns,snakes}
\begin{document}
\begin{tikzpicture}{every node/.style={draw,outer sep=0pt,thick}}
\node (ground) [fill,gray, pattern=north east lines,minimum width=5cm,%
minimum height=.3cm,anchor=north,draw=none] {};
\node (M1) [draw,minimum width=0.1cm,minimum height=0.1cm] at (-2,-2) {m};
\draw [ snake=coil, segment amplitude=5pt, segment length=5pt] (ground.south) -- (M1);
\node (M2) [draw,minimum width=0.1cm,minimum height=0.1cm] at (-1.5,-2.5) {m};
\draw [ snake=coil, segment amplitude=5pt, segment length=5pt] (ground.south) -- (M2);
\end{tikzpicture}
\end{document}

The first problem I've encountered is that the ground pattern is filled and do not exhibit the pattern with oblique lines. The second problem I do not know how to position correctly the different masses. By the wave the distances and elongation of the masses follows a sinusoidal shape so I think there should be a way to place them automatically.

share|improve this question
    
Welcome to TeX.sx! Please always add a full, but minimal working example (MWE) that illustrates your problem. It's not necessary to begin your posts with a greeting or closing. Please make sure that all images are uploaded using the official stackexchange interface, i.e. the image icon on top of the text field (shortcut: CTRL+G). This ensures that all images are always accessible and do not expire. –  Martin Scharrer Nov 7 '11 at 11:07
add comment

1 Answer

up vote 17 down vote accepted

Updated answer

A first attempt with coil springs (need to be improved to take care of the natural length of the spring).

enter image description here

\documentclass[tikz]{standalone}

\usetikzlibrary{decorations.pathmorphing,calc,patterns}

\makeatletter

\def\pgfdecorationspringstraightlinelength{.5cm}
\def\pgfdecorationspringnumberofelement{8}
\def\pgfdecorationspringnaturallength{5cm}
\pgfkeys{%
  /pgf/decoration/.cd,
  spring straight line length/.code={%
    \pgfmathsetlengthmacro\pgfdecorationspringstraightlinelength{#1}},
  spring natural length/.code={%
    \pgfmathsetlengthmacro\pgfdecorationspringnaturallength{#1}},
  spring number of element/.store in=\pgfdecorationspringnumberofelement
}

\pgfdeclaredecoration{coil spring}{straight line}{%
  \state{straight line}[%
    persistent precomputation = {%
      % Compute the effective length of the spring (without the length
      % of the two straight lines): \pgfdecorationspringeffectivelength
      \pgfmathsetlengthmacro{\pgfdecorationspringeffectivelength}%
        {\pgfdecoratedpathlength-2*\pgfdecorationspringstraightlinelength}
      % Compute the effective length of one coil pattern:
      % \pgfdecorationspringeffectivelengthofonecoil
      \pgfmathsetlengthmacro{\pgfdecorationspringeffectivelengthofonecoil}%
        {\pgfdecorationspringeffectivelength/\pgfdecorationspringnumberofelement}
    },
    width = \pgfdecorationspringstraightlinelength,
    next state = draw spring]{%
      \pgfpathlineto{%
        \pgfqpoint{%
          \pgfdecorationspringstraightlinelength}{0pt}}
  }
  \state{draw spring}%
    [width=\pgfdecorationspringeffectivelengthofonecoil,
     repeat state=\pgfdecorationspringnumberofelement-1,next state=final]{%
       \pgfpathcurveto
         {\pgfpoint@onspringcoil{0    }{ 0.555}{1}}
         {\pgfpoint@onspringcoil{0.445}{ 1    }{2}}
         {\pgfpoint@onspringcoil{1    }{ 1    }{3}}
       \pgfpathcurveto
         {\pgfpoint@onspringcoil{1.555}{ 1    }{4}}
         {\pgfpoint@onspringcoil{2    }{ 0.555}{5}}
         {\pgfpoint@onspringcoil{2    }{ 0    }{6}}
       \pgfpathcurveto
         {\pgfpoint@onspringcoil{2    }{-0.555}{7}}
         {\pgfpoint@onspringcoil{1.555}{-1    }{8}}
         {\pgfpoint@onspringcoil{1    }{-1    }{9}}
       \pgfpathcurveto
         {\pgfpoint@onspringcoil{0.445}{-1    }{10}}
         {\pgfpoint@onspringcoil{0    }{-0.555}{11}}
         {\pgfpoint@onspringcoil{0    }{ 0    }{12}}
  }
  \state{final}{%
    \pgfpathlineto{\pgfpointdecoratedpathlast}
  }
}

\def\pgfpoint@onspringcoil#1#2#3{%
  \pgf@x=#1\pgfdecorationsegmentamplitude%
  \pgf@x=.5\pgf@x%
  \pgf@y=#2\pgfdecorationsegmentamplitude%
  \pgfmathparse{0.083333333333*\pgfdecorationspringeffectivelengthofonecoil}%
  \pgf@xa=\pgfmathresult pt
  \advance\pgf@x by#3\pgf@xa%
}


\makeatother

\tikzset{%
  Spring/.style = {%
    decoration = {%
      coil spring,
      spring straight line length = .5cm,
      % To be added
      spring natural length = #1,
      spring number of element = 8,
      amplitude=3mm},
    decorate,
    very thick},
  Spring/.default = {4cm}}


\begin{document}

\begin{tikzpicture}
  \def\SpringNaturalLength{4cm}%
  \def\xMax{10}%
  \pgfmathdeclarefunction{wave}{1}{%
    \pgfmathparse{\SpringNaturalLength*(1+.5*cos(\x*40))}}
  \filldraw[gray,pattern=north east lines] (0,0) -| (\xMax,.2) -| (0,0);
  \foreach \x in {0,0.75,...,\xMax}{%
    \draw[Spring] (\x,0) -- node[at end,fill=red,circle] {} (\x,{-wave(\x)});}
\end{tikzpicture}
\end{document}

Original answer

Something like that (sorry, I do not use a coil to represent a spring).

Wave spring

\documentclass[tikz]{standalone}

\usetikzlibrary{decorations.pathmorphing,calc,patterns}

\makeatletter

\def\pgfdecorationspringstraightlinelength{.5cm}
\def\pgfdecorationspringnumberofelement{8}
\def\pgfdecorationspringnaturallength{5cm}
\pgfkeys{%
  /pgf/decoration/.cd,
  spring straight line length/.code={%
    \pgfmathsetlengthmacro\pgfdecorationspringstraightlinelength{#1}},
  spring natural length/.code={%
    \pgfmathsetlengthmacro\pgfdecorationspringnaturallength{#1}},
  spring number of element/.store in=\pgfdecorationspringnumberofelement
}

\pgfdeclaredecoration{zig zag spring}{straight line}{%
  \state{straight line}[%
    persistent precomputation = {%
      % Compute the effective length of the spring (without the length
      % of the two straight lines): \pgfdecorationspringeffectivelength
      \pgfmathsetlengthmacro{\pgfdecorationspringeffectivelength}%
        {\pgfdecoratedpathlength-2*\pgfdecorationspringstraightlinelength}
      % Compute the effective length of one zigzag pattern:
      % \pgfdecorationspringeffectivelengthofonezigzag
      \pgfmathsetlengthmacro{\pgfdecorationspringeffectivelengthofonezigzag}%
        {\pgfdecorationspringeffectivelength/\pgfdecorationspringnumberofelement}
      % Compute the effective length of one forth of zigzag pattern:
      % \pgfdecorationspringeffectivelengthofoneforthofzigzag
      \pgfmathsetlengthmacro{%
        \pgfdecorationspringeffectivelengthofoneforthofzigzag}%
        {\pgfdecorationspringeffectivelengthofonezigzag/4}
      % Compute the length of a forth of one zigzag (fixed by spring
      % constants)
      % 4=1/4
      % 0.707=cos(45°)
      \pgfmathsetlengthmacro{\pgfdecorationspringlengthofaforthzigzag}%
        {\pgfdecorationspringnaturallength 
          /(\pgfdecorationspringnumberofelement*4*0.707)}
      % Compute the (semi) heigth
      \pgfmathsetlengthmacro{\pgfdecorationspringeffectivesemiheigth}%
        {sqrt(abs(\pgfdecorationspringlengthofaforthzigzag^2-
          \pgfdecorationspringeffectivelengthofoneforthofzigzag^2))}%
    },
    width = \pgfdecorationspringstraightlinelength,
    next state = draw spring]{%
      \pgfpathlineto{%
        \pgfqpoint{%
          \pgfdecorationspringstraightlinelength}{0pt}}
  }
  \state{draw spring}%
    [width=\pgfdecorationspringeffectivelengthofonezigzag,
     repeat state=\pgfdecorationspringnumberofelement-1,next state=final]{%
      \pgfpathlineto{%
        \pgfqpoint{%
          \pgfdecorationspringeffectivelengthofoneforthofzigzag}{%
          \pgfdecorationspringeffectivesemiheigth}}
       \pgfpathlineto{%
        \pgfpoint{%
          3*\pgfdecorationspringeffectivelengthofoneforthofzigzag}{%
          -\pgfdecorationspringeffectivesemiheigth}}
       \pgfpathlineto{%
        \pgfpoint{%
          4*\pgfdecorationspringeffectivelengthofoneforthofzigzag}{0pt}}
  }
  \state{final}{%
    \pgfpathlineto{\pgfpointdecoratedpathlast}
  }
}

\makeatother

\tikzset{%
  Spring/.style = {%
    decoration = {%
      zig zag spring,
      spring straight line length = .5cm,
      spring natural length = #1,
      spring number of element = 5},
    decorate,
    very thick},
  Spring/.default = {4cm}}


\begin{document}

\begin{tikzpicture}
  \def\SpringNaturalLength{4cm}%
  \def\xMax{10}%
  \pgfmathdeclarefunction{wave}{1}{%
    \pgfmathparse{\SpringNaturalLength*(1+.5*cos(\x*40))}}
  \filldraw[gray,pattern=north east lines] (0,0) -| (\xMax,.2) -| (0,0);
  \foreach \x in {0,0.75,...,\xMax}{%
    \draw[Spring] (\x,0) -- node[at end,fill=red,circle] {} (\x,{-wave(\x)});}
\end{tikzpicture}

\end{document}
share|improve this answer
    
Thank you very much, very nice realization. In order to reproduce exactly the figure I think I've to change from sin to cos in \SpringRestLength*(1+.5*cos(\x*40))} in order to have the first and last spring at rest. Is that correct? –  Nicola Vianello Nov 7 '11 at 12:28
    
Yes, change to cos(\x*36). –  cjorssen Nov 7 '11 at 12:34
    
thanks very nice. I will go through your code in order to understand how to enlarge the number of sines (if you look at the figure it has more than 1 period) –  Nicola Vianello Nov 7 '11 at 12:40
    
Just change \xMax to a higher value or change the "period", that is the factor in the argument of the cosine. –  cjorssen Nov 7 '11 at 12:44
    
thanks I like it very much. –  Nicola Vianello Nov 7 '11 at 12:52
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.