7

Does anyone have a macro for an "angular spring" ? I'm looking for something similar to that in pst-coil (PS-Tricks package) but the geometry of the "spring" is not straight but an arch (with eventually, variable opening).

  • 4
    \begin{commercial} If you consider using TikZ, you could look e.g. here. \end{commercial} – user121799 Jan 19 at 2:40
11

Run with lualatex:

\documentclass{article} 
\usepackage{luamplib}
\begin{document}
\begin{mplibcode}
input metaobj
beginfig(1);
  newCircle.a(btex start etex);
  newCircle.b(btex end etex);
  a.c=origin;
  b.c-a.c=(3cm,2cm);
  drawObj(a,b);
  nccoil(a)(b) "coilwidth(3mm)", "linetension(0.8)",
               "angleA(-20)", "angleB(90)", "arrows(-)","linewidth(1pt)";
endfig;

clearObj a,b;
beginfig(2);
  newCircle.a(btex start etex);
  newCircle.b(btex end etex);
  a.c=(0cm,3cm);
  b.c=(5cm,4cm);
  drawObj(a,b);
  nccoil(a)(b) "doubleline(true)","coilwidth(3mm)","linetension(0.8)",
               "angleA(-90)", "angleB(90)", "arrows(-)","linewidth(1pt)";
endfig;
\end{mplibcode}
\end{document}

enter image description here

3

Another pstricks based solution for this problem can be achieved by using pst-solides3d and abusing the helix itself.

%&pdflatex
% !TeX TXS-program:compile = txs:///pdflatex/[--shell-escape]
\documentclass[a4paper, pdf, x11names]{standalone}
\usepackage{pstricks}
\usepackage{pstricks-add, auto-pst-pdf}
\usepackage{pst-solides3d}
\begin{document}
    \begin{pspicture}[solidmemory](-6.5,-3.5)(6.5,3)
    \psset{viewpoint=30 0 15 rtp2xyz,Decran=30,lightsrc=viewpoint}
    \pstVerb{/R1 5 def /R0 2 def /k 20 def /RL 0.15 def /kRL 40 def}%
    %https://tex.stackexchange.com/questions/151108/showcase-of-translations-to-asymptote-from-tikz-pstricks
    % abusing the helix to create a sprial spring-like structure
    \defFunction[algebraic]{helix}(t)
    {(R1+R0*cos(k*t))*sin(t)+RL*sin(kRL*k*t)}
    {(R1+R0*cos(k*t))*cos(t)+RL*cos(kRL*k*t)}
    {R0*sin(k*t)+RL*sin(kRL*k*t)}
    \psSolid[object=courbe,
    resolution=7800,
    fillcolor=white,incolor=black,
    r=0,
    range=-0.099 0,
    function=helix,action=none,name=Helix]%
    \psSolid[object=fusion,base=Helix]
    % start-stop circles
    \pscircle(4,-1.25){0.3}
    \pscircle(7.1,0.3){0.3}
    % texts
    \rput[c](4,-1.25){\tiny Stop}
    \rput[c](7.1,0.3){\tiny Start}
    %\put(-1,-3){$\text{multiples of 6}$}
    \end{pspicture}
\end{document}

which would give you:

enter image description here

Here one can play with the parameters in

\pstVerb{/R1 5 def /R0 2 def /k 20 def /RL 0.15 def /kRL 40 def}%

to get much more exotic variations.

3

The trivial balls at the ends are intentionally removed for the sake of simplicity.

\documentclass[pstricks,border=1cm]{standalone}
\usepackage{pst-plot}
\newcommand\circularSpring[4][]{%
    \curvepnodes[plotpoints=\numexpr#4*4+1]{#2 DegtoRad}{#3 DegtoRad}
        {(sin(#4*t)/5+2)*cos(t)|(sin(#4*t)/5+2)*sin(t)}{A}
    \psnline[linejoin=1,#1](0,\Anodecount){A}}


\begin{document}
\begin{pspicture}[showgrid](-3,-3)(3,3)
    \pscircle[linecolor=red,linestyle=dashed]{2}
    \circularSpring{45}{90}{100}
    \circularSpring{0}{-90}{200}
\end{pspicture}
\end{document}

enter image description here

Edit

Almost forgotten animation.

\documentclass[pstricks]{standalone}
\usepackage{pst-plot}
\newcommand\circularSpring[4][]{%
    \curvepnodes[plotpoints=\numexpr#4*4+1]{#2 DegtoRad}{#3 DegtoRad}
        {(sin(#4*t)/5+2)*cos(t)|(sin(#4*t)/5+2)*sin(t)}{A}
    \psnline[linejoin=1,#1](0,\Anodecount){A}}


\begin{document}
\multido{\i=0+36}{11}{%
\begin{pspicture}(-3,-3)(3,3)
    \pscircle[linecolor=red,linestyle=dashed]{2}
    \circularSpring{0}{\i}{50}
\end{pspicture}}
\end{document}

enter image description here

Note: few glitches due to incorrectly sampled points are left for your exercises.

2
+500

[edit] Since I have been granted this bounty by "artificial" means I have decided to upcycle it please see Bountiful 2019 Questions

Not an answer but just a comment (with visual)

There are many excellent answers. (I love the marmot with a spring in the air)

However did I misread the question that what was wanted ? was it a coil with two "angles" i.e. with one flat side and one arched e.g. half of this

enter image description here

and what is meant by "variable opening" (but as OP has not been seen since posting) I guess that's moot. I'm thinking variable like this
enter image description here

  • A nice answer. You won! – Money Oriented Programmer Jan 23 at 13:25
  • 3
    @GodMustBeCrazy I now feel double guilty (again :-) I did not even attempt an answer God must be really crazy but who am I to doubt his mysterious ways. – user170109 Jan 23 at 13:40
  • 1
    @ArtificialStupidity On checking back It was my treble inartificial stupidity to not look more closely at who awarded the bonus THANKS – user170109 Jan 23 at 17:35
0

A SkiaSharp solution just for comparison purpose. It can embed LaTeX equations as well.

using SkiaSharp; // needs skiasharp nuget
using System.Diagnostics;
using static System.Math;


class CircularSpring
{
    static readonly SKPaint blackStrokePaint = new SKPaint
    {
        Style = SKPaintStyle.Stroke,
        StrokeWidth = .05f,
        Color = SKColors.Black,
        StrokeCap = SKStrokeCap.Round,
        IsAntialias = true
    };

    static readonly SKPaint redStrokePaint = new SKPaint
    {
        Style = SKPaintStyle.Stroke,
        StrokeWidth = .05f,
        Color = SKColors.Red,
        StrokeCap = SKStrokeCap.Round,
        IsAntialias = true
    };

    static readonly float scale = SKDocument.DefaultRasterDpi / 2.54f; // dots per cm
    static readonly float width = 6 * scale; // 6 cm
    static readonly float height = 6 * scale; // 6 cm

    static readonly int k = 50; // wave number
    static readonly int plotPoints = 4 * k + 1;
    static readonly double dt = PI * 2 / (plotPoints - 1);

    private static SKPoint GetPoint(int index)
    {
        double t = index * dt;
        return new SKPoint
            (
                (float)((Sin(k * t) / 5 + 2) * Cos(t)),
                (float)((Sin(k * t) / 5 + 2) * Sin(t))
            );
    }

    public static void Generate(string filename)
    {
        using (var stream = new SKFileWStream($"{filename}.pdf"))
        using (var document = SKDocument.CreatePdf(stream))
        using (var canvas = document.BeginPage(width, height))
        {

            // translate first and then scale, don't reverse!
            canvas.Translate(width / 2, height / 2);
            canvas.Scale(scale);

            // draw a red circle
            canvas.DrawCircle(0, 0, 2, redStrokePaint);

            // draw a circular spring
            for (int i = 0; i < plotPoints - 1; i++)
                canvas.DrawLine(GetPoint(i), GetPoint(i + 1), blackStrokePaint);

            document.EndPage();
        }
    }
}

class Test
{
    static void Main()
    {
        string filename = nameof(CircularSpring);
        CircularSpring.Generate(filename);

        // convert to PNG with ImageMagick
        using (Process p = new Process())
        {
            p.StartInfo.FileName = "magick";
            p.StartInfo.Arguments = $"convert -compose copy -bordercolor red -border 2x2 -density 200 -alpha remove {filename}.pdf {filename}.png";
            p.Start();
        }
    }
}

enter image description here

enter image description here

  • 1
    that is a simple \pszigzag from pst-coil – user2478 Jan 23 at 11:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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