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).
- 15,156
- 71
- 1
5 Answers
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}
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:
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.
- 648
- 4
- 20
- 53
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}
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}
Note: few glitches due to incorrectly sampled points are left for your exercises.
- 46,933
[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
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

-
-
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. – Jan 23 '19 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 – Jan 23 '19 at 17:35
A SkiaSharp solution just for comparison purpose. It can embed LaTeX equations as well.
using SkiaSharp;
using System.Diagnostics;
using static System.MathF;
class Diagram
{
const float scale = SKDocument.DefaultRasterDpi / 2.54f; // dots per cm
static float PtToCm(float pt) => pt / scale;
static readonly SKPaint blackStrokePaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
StrokeWidth = PtToCm(0.8f),
Color = SKColors.Black,
StrokeCap = SKStrokeCap.Round,
IsAntialias = true
};
static readonly SKPaint redStrokePaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
StrokeWidth = PtToCm(0.8f),
Color = SKColors.Red,
StrokeCap = SKStrokeCap.Round,
IsAntialias = true
};
static readonly SKRect domain = new SKRect(-2.5f, 2.5f, 2.5f, -2.5f);
static readonly float width = domain.Width * scale;
static readonly float height = -domain.Height * scale;
static readonly int k = 50; // wave number
static readonly int plotPoints = 4 * k + 1;
static readonly float dt = PI * 2 / (plotPoints - 1);
private static SKPoint GetPoint(int index)
{
float t = index * dt;
return new SKPoint
(
(Sin(k * t) / 5 + 2) * Cos(t),
(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))
{
canvas.Scale(scale, -scale);
canvas.Translate(-domain.Left, -domain.Top);
canvas.DrawCircle(0, 0, 2, redStrokePaint);
for (int i = 0; i < plotPoints - 1; i++)
canvas.DrawLine(GetPoint(i), GetPoint(i + 1), blackStrokePaint);
document.EndPage();
}
}
}
class Invoker
{
static void Main()
{
string filename = "CircularSpring";
Diagram.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();
p.WaitForExit();
}
}
}
- 46,933






\begin{commercial}If you consider using TikZ, you could look e.g. here.\end{commercial}– Jan 19 '19 at 02:40