当人们在连续旋转的画布上反复绘制闭合曲线时,就会得到类似螺旋形的图画。有没有使用 TikZ 或 PSTricks 制作螺旋形图画的好方法?有一个不错的 PSTricks例子来自 PracTeX 期刊,但它仅涵盖圆绕圆旋转的情况。
我想到了一个更普遍的问题。是否可以连续旋转参数化的封闭曲线以获得如下所示的螺旋图像?
这个问题的理想答案是允许人们指定闭合曲线的参数化以及曲线必须重复的次数的代码。
答案1
这里的基本思想是使用 TikZ 绘制图片时不断旋转纸张。
这当然是不可能的。
这样做的困难在于,这样做所得到的路径不一定由直线和三次贝塞尔曲线组成,而这正是 PGF 所知道如何生成的。
但曲线实际上只是许多短直线,因此如果我们用许多短直线替换曲线并旋转这些短直线的端点,我们也许能够实现一些目标。我最初的想法是使用装饰来实现这一点,但我遇到了困难,因为装饰(很有用!)会将您转换为路径的坐标系(在当前点),而我们想要应用独立于此坐标系的变换。我没有追求这一点,而是使用了一些我碰巧拥有的代码,这些代码是我开发的,用于在路径上执行比目前更复杂的操作。我已经有了用于平移路径和反转路径的代码,所以我只需要添加增量旋转和一些装饰。
这文档代码如下:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations}
\usepackage{spath}
\begin{document}
\begin{tikzpicture}
\path[decoration={curveto},decorate,save path=\tmppath] (2,0) to[bend right] (4,2) to[bend right] (5,0) to[bend right] (2,0);
\pgfoonew \opath=new spath(\tmppath)
\opath.prepare()
\opath.spirograph(,0pt,0pt,36)
\opath.use path with tikz(draw,blue)
\end{tikzpicture}
\end{document}
看起来又漂亮又简单!下面是它的功能:
线条
\path
设置了要重复和扭曲的路径。它不会渲染它,而是将其保存到宏 (\tmppath
)。它确实做了一件非常重要的事情:用装饰来装饰它curveto
。这会用许多小线条替换路径,这使得其余部分看起来更好,因为旋转应用得更均匀。接下来,我们使用它
\tmppath
来实例化“软路径对象”(spath
)。这将使用我的库来允许我们操纵路径。我们准备路径(不是严格必要的 - 方法检查是否已经完成)。
现在我们“旋转”路径。这里发生的事情是 TeX 沿着路径行走,对到达的每个坐标应用旋转。每次,它都会旋转一点角度,以便路径逐渐弯曲。一旦它对原始路径执行了此操作,它就会复制此路径正确的次数,将其复制并将副本焊接在一起以形成围绕圆圈的完整路径。
spirograph 命令的(逗号分隔的)参数是:1)用于保存路径的宏(在这种情况下为空,意味着我们应该就地修改路径),2)和 3)是旋转的原点,4)是绕圆重复的次数。
结果:
缺点:
- 该
spath
图书馆尚未加入 CTAN。高度实验性的。你可以从TeX-SX 启动板页面(您需要最新版本,我今天才添加这个)。 - 这是极其很慢。在我的系统上,上面的代码编译花了 24 秒。
- 路径最终并没有闭合 - 这很容易修复,我只是还没有这样做。
答案2
这是一个使用循环的初步示例(取决于您要查找的内容)for
,
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\def\repeatno{40}
\node[inner sep=0.5cm,circle] (base) at (0,0) {};
\foreach \x in {1,2,...,\repeatno}{
\draw[rotate=(\x*360/\repeatno)-90] (base.\x*360/\repeatno) to [in=-70,out=70] ++(0,2) to [in=90,out=-30] ++(1.3,-2) to [in=20,out=160] +(-1.3,0);
}
\end{tikzpicture}
\end{document}
这使
第二次经过一些修改后,我能够获得曲线,除了收尾部分。但我真的对此很兴奋 :) 可能会在某些国家被禁止。以下是我所做的(略有失败)
\begin{tikzpicture}
\def\repeatno{12}
\node[inner sep=0.5cm,circle] (base) at (0,0) {};
\foreach[remember=\x as \lastx (initially 1)] \x in {1,2,...,13} {
\draw[rotate=(\x*360/\repeatno)-90] (base.\x*360/\repeatno) to [in=-70,out=70] ++(0,2)%
to [in=90,out=-30] ++(1.3,-2) to [in=20,out=160] (base.\lastx*360/\repeatno);
}
\end{tikzpicture}
结果(减少重复次数以使工件可见)
似乎我需要一个额外的步骤来在foreach
循环后正确闭合曲线。请随时纠正或改进
拍摄 3已修复(尽管可能没有自动化版本)
\begin{tikzpicture}
\def\repeatno{24}
\node[inner sep=0.5cm,circle] (base) at (0,0) {};
\foreach[remember=\x as \lastx (initially 1)] \x in {2,...,23} {
\draw[rotate=(\x*360/\repeatno)-90] (base.\x*360/\repeatno) to [in=-70,out=70] ++(0,2)%
to [in=90,out=-30] ++(1.3,-2) to [in=20,out=160] (base.\lastx*360/\repeatno);
}
\draw[rotate=360/\repeatno-90] (base.360/\repeatno) to [in=-70,out=70] ++(0,2)%
to [in=90,out=-30] ++(1.3,-2) to [in=20,out=160] (base.0);
\draw[rotate=-90] (base.0*360/\repeatno) to [in=-70,out=70] ++(0,2) to [in=90,out=-30] ++(1.3,-2) to [in=20,out=160] (base.-1*360/\repeatno);
\end{tikzpicture}
结果如下
请告诉我们您到底想如何参数化曲线。我使用了一些目测方法,但您可能已经想到了具体的例子。
答案3
我不确定我是否真正理解了这个问题。首先我画一条封闭的曲线,然后我旋转这条曲线,但这样做并不困难,也许我走错了路!
第一条曲线:封闭曲线被命名为\myclosedcurve
\documentclass[11pt]{scrartcl}
\usepackage{tikz}
\begin{document}
\def\spirographlike#1{%
\def\repeatno{#1}
\foreach \i in {1,...,\repeatno}
{%
\begin{scope}[rotate=360/\repeatno*\i]
\mycloedcurve
\end{scope}}%
}
\def\mycloedcurve{\draw (1,0)--(-0.5,0.433)--(-0.5,-0.433)--cycle;}
\begin{tikzpicture}
\draw[red,->] (0,0)--(1,0) (0,0)--(0,1); \mycloedcurve
\end{tikzpicture}
\begin{tikzpicture}[scale=4]
\spirographlike{24}
\end{tikzpicture}
\def\mycloedcurve{ \draw (1,0)--(2,0.433)--(0.5,0.866)--cycle;}
\begin{tikzpicture}
\draw[red,->] (0,0)--(1,0) (0,0)--(0,1); \mycloedcurve
\end{tikzpicture}
\begin{tikzpicture}[scale=2]
\spirographlike{36}
\end{tikzpicture}
\end{document}
2)一条更复杂的曲线,我用我的包tkz-fct
画了这条曲线
\documentclass[11pt]{scrartcl}
\usepackage{tkz-fct}
\begin{document}
\def\spirographlike#1{%
\def\repeatno{#1}
\foreach \i in {1,...,\repeatno}
{%
\begin{scope}[rotate=360/\repeatno*\i]
\mycloedcurve
\end{scope}}%
}
\def\mycloedcurve{\tkzFctPolar[domain=0:2*pi,samples=400]{ 1-sin(t)}}
\begin{tikzpicture}
\draw[red,->] (0,0)--(1,0) (0,0)--(0,1); \mycloedcurve
\end{tikzpicture}
\begin{tikzpicture}[scale=2]
\tkzInit [xmin=-5,xmax=5,ymin=-5,ymax=5]
\spirographlike{40}
\end{tikzpicture}
\end{document}
答案4
使用 PSTricks。
心
\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-plot}
\psset{linejoin=1,algebraic,dimen=monkey,linecolor=red,plotpoints=100}
\def\N{6}
\def\R{2}
\def\heart{\psparametricplot{0}{2 Pi mul}{sin(t)^3 | (13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t))/16}}
\degrees[\N]
\begin{document}
\begin{pspicture}(-3,-3)(3,3)
\pscircle[linecolor=blue,linestyle=dashed]{\R}
\multido{\i=0+1}{\N}{\uput{\R}[\i]{\i}{\heart}}
\end{pspicture}
\end{document}
为了N=50
。