中心 TikZ 路径装饰

中心 TikZ 路径装饰

我想用 TikZcoil装饰画一个春天,但如果不手动进行微调,我就无法将其置于路径的中心。

例子:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}

\begin{document}
\begin{tikzpicture}
  \draw
    [%
      thick,
      decoration=
        {%
          coil,
          amplitude=0.5cm,
          aspect=0.7,
          pre length=0.5cm,
          post length=0.5cm,
          segment length=1cm,
        },%
      decorate,
    ]
  (0,0) -- (5cm, 0);
\end{tikzpicture}
\end{document}

不居中 tikz 装饰

弹簧不对称,左右两侧的长度不一样。

有没有办法自动计算pre lengthpost length参数segment length以获得对称弹簧?

答案1

你可以这样做:

编辑:为了补偿纵横比小于 0.5 时的舍入误差,请更改amplitude=(0.5*\pgfdecorationsegmentlength)/ (2*\pgfdecorationsegmentaspect)amplitude=(0.49*\pgfdecorationsegmentlength)/ (2*\pgfdecorationsegmentaspect)

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}
\newcounter{Nocoils}
\setcounter{Nocoils}{3}
\newlength{\lengthspr}
\setlength{\lengthspr}{5cm}
\newlength{\preandpostlens}
\setlength{\preandpostlens}{0.3cm}
\tikzset{
/pgf/decoration/pre length=\preandpostlens,
/pgf/decoration/post length=\preandpostlens
}

\begin{document}
\begin{tikzpicture}
\setlength{\lengthspr}{5.21cm}
\setcounter{Nocoils}{5}
\draw
    [%
      thick,
      decoration=
        {%
          coil,
          aspect=0.7,
          segment length=(\lengthspr-2*\pgfkeysvalueof{/pgf/decoration/pre length})/(\value{Nocoils}),
          amplitude=(0.49*\pgfdecorationsegmentlength)/ (2*\pgfdecorationsegmentaspect),  
        },%
      decorate,
    ]
  (0,0) -- (\lengthspr, 0);
\end{tikzpicture}

\begin{tikzpicture}
\setlength{\lengthspr}{4cm}
\setlength{\preandpostlens}{0.72cm}
\setcounter{Nocoils}{4}
\draw
    [%
      thick,
      decoration=
        {%
          coil,
          aspect=0.27,
          segment length=(\lengthspr-2*\preandpostlens)/(\value{Nocoils}),
          amplitude=(0.49*\pgfdecorationsegmentlength)/ (2*\pgfdecorationsegmentaspect),  
        },%
      decorate,
    ]
  (0,0) -- (\lengthspr, 0);
\end{tikzpicture}
\end{document}

在此处输入图片描述

编辑:我建议另一种方法,即对每个弹簧使用相同的段长度,然后计算相应的线圈数,前长度和后长度取决于弹簧的总长度。也许这更可能是你想要的:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}


\newlength{\lengthspr}
\setlength{\lengthspr}{5cm}
\newlength{\seglens}
\setlength{\seglens}{0.5cm}
\newcounter{Nocoils}
\setcounter{Nocoils}{\fpeval{floor(\lengthspr/\seglens,0)}}
\newlength{\preandpostlens}
\setlength{\preandpostlens}{\fpeval{(\lengthspr-(\value{Nocoils}*\seglens))/2cm}cm}
\tikzset{
/pgf/decoration/pre length=\preandpostlens,
/pgf/decoration/post length=\preandpostlens
}

\begin{document}
\begin{tikzpicture}
\setlength{\lengthspr}{3.31cm}
\draw
    [%
      thick,
      decoration=
        {%
          coil,
          aspect=0.33,
          segment length=\seglens,
          amplitude=(0.49*\pgfdecorationsegmentlength)/ (2*\pgfdecorationsegmentaspect),  
        },%
      decorate,
    ]
  (0,0) -- (\lengthspr, 0);
\end{tikzpicture}

\begin{tikzpicture}
\setlength{\lengthspr}{5.21cm}
\setcounter{Nocoils}{\fpeval{floor(\lengthspr/\seglens,0)}}
\setlength{\preandpostlens}{\fpeval{(\lengthspr-(\value{Nocoils}*\seglens))/2cm}cm}
\draw
    [%
      thick,
      decoration=
        {%
          coil,
          aspect=0.33,
          segment length=\seglens,
          amplitude=(0.49*\pgfdecorationsegmentlength)/ (2*\pgfdecorationsegmentaspect),  
        },%
      decorate,
    ]
  (0,0) -- (\lengthspr, 0);
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

在@Tom 的回答的帮助下,我进一步研究了一下。装饰的定义coil在文件中给出pgflibrarydecorations.pathmorphing.code.tex,并以

\pgfdeclaredecoration{coil}{coil}
{%
  \state{coil}[switch if less than=%
    1.5\pgfdecorationsegmentlength+%
    \pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude+%
    \pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude to last,
               width=+\pgfdecorationsegmentlength]
...

好的图案长度也是如此\pgfdecorationsegmentlength,但困难在于最后的部分coil较长,至少需要0.5\pgfdecorationsegmentlength + 2*\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude

换句话说,如果

  • L是路径的全长,
  • p等于pre lengthpost length
  • s是个segment length
  • a是个amplitude
  • x是个aspect
  • n是线圈数,那么
L = p + n⋅s + 0.5⋅s + 2⋅x⋅a + p

使用TikZ:根据路径长度计算“预长度”,我可以使用 获得完整路径长度\pgfmetadecoratedpathlength,但如果我尝试设置 ,它不起作用amplitude。所以我决定改为使用以下pre length方法设置:

pre length=
        (
          \pgfkeysvalueof{/pgf/decoration/min prepost length}
          + 0.5*
            (
            \pgfmetadecoratedpathlength
              - 2*\pgfkeysvalueof{/pgf/decoration/min prepost length}
              - 2*\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude
              - 0.5\pgfdecorationsegmentlength
              - \pgfdecorationsegmentlength*floor
                (
                  (
                    \pgfmetadecoratedpathlength
                    - 2*\pgfkeysvalueof{/pgf/decoration/min prepost length}
                    - 2*\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude
                    - 0.5\pgfdecorationsegmentlength
                  )
                  /\pgfdecorationsegmentlength
                )
            )
        )

mod函数本来可以使这个表达式更清晰,但我得到了有关扩展的错误)。这里有一个专用键,用于确保和的/pgf/decoration/min prepost length最小值。请注意,从数学上讲,第一个与取消,但为了清楚起见,我保留了它们。pre lengthpost length\pgfkeysvalueof{/pgf/decoration/min prepost length}0.5*(- 2*\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude)

我现在得到了一个几乎所有时间都能正常工作的计算(除了当aspect为负数时,如果aspect*amplitude大于segment length,但对我来说已经足够了)。

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}

\tikzset{%
  ,/pgf/decoration/min prepost length/.initial=2mm
  ,coil spring/.style={%
    ,thick
    ,smooth
    ,decorate
    ,decoration={
      ,coil
      ,aspect=0.5
      ,segment length=2mm
      ,amplitude=2mm
      ,pre length=
        (
          \pgfkeysvalueof{/pgf/decoration/min prepost length}
          + 0.5*
            (
            \pgfmetadecoratedpathlength
              - 2*\pgfkeysvalueof{/pgf/decoration/min prepost length}
              - 2*\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude
              - 0.5\pgfdecorationsegmentlength
              - \pgfdecorationsegmentlength*floor
                (
                  (
                    \pgfmetadecoratedpathlength
                    - 2*\pgfkeysvalueof{/pgf/decoration/min prepost length}
                    - 2*\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude
                    - 0.5\pgfdecorationsegmentlength
                  )
                  /\pgfdecorationsegmentlength
                )
            )
        )
      ,post length=\pgfkeysvalueof{/pgf/decoration/min prepost length}
    }
  }
}

\begin{document}
\begin{tikzpicture}
  \draw[gray, very thin, step=2mm] (0,-1) grid (5,4);
  \draw (0,-1) grid (5,4);
  \draw
    [%
      ,coil spring, ultra thick
    ]
  (0,3) -- +(5cm, 0);
  \draw
    [%
      ,coil spring, ultra thick
      ,decoration={aspect=0.5, amplitude=0.5cm, segment length=1cm}
    ]
  (0,2) -- +(4.5cm, 0);
  \draw
    [%
      ,coil spring, ultra thick
      ,decoration={aspect=0.3, amplitude=0.5cm, segment length=1cm}
    ]
  (0,1) -- +(5cm, 0);
  \draw
    [%
      ,coil spring, ultra thick
      ,decoration={aspect=-0.2, amplitude=0.5cm, min prepost length=1cm}
    ]
  (0,0) -- +(5cm, 0);
\end{tikzpicture}
\end{document}

预长度计算解决方案

相关内容