有人有“角弹簧”的宏吗?我在 (PS-Tricks 包) 中寻找类似的东西,pst-coil
但“弹簧”的几何形状不是直线而是拱形(最终具有可变开口)。
答案1
运行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}
答案2
解决这个问题的另一种pstricks
方法是通过使用pst-solides3d
和滥用螺旋本身。
%&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}
这将给你:
在这里,你可以使用以下参数
\pstVerb{/R1 5 def /R0 2 def /k 20 def /RL 0.15 def /kRL 40 def}%
以获得更多奇特的变化。
答案3
为了简单起见,末端的琐碎球被故意删除。
\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}
编辑
几乎被遗忘的动画。
\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}
注意:由于错误采样点而导致的练习中会出现一些小故障。
答案4
SkiaSharp 解决方案仅用于比较目的。它也可以嵌入 LaTeX 方程式。
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();
}
}
}