在 tikz/pgf 中将贝塞尔曲线分割成相等的长度

在 tikz/pgf 中将贝塞尔曲线分割成相等的长度

我正在尝试绘制两条曲线,然后使用 pgf/tikz 创建大小相同的线段/圆弧,但由于某种原因,这些线段的大小并不相同。我想继续使用径向阴影为每个线段填充不同的颜色。我本以为这是标准做法,但我对它看起来有多难感到惊讶。也许我的方法不对?我也尝试过使用带圆弧的椭圆,但线段大小在极点处再次变小。

\documentclass{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}[scale=1]

\tikzstyle{help lines}=[blue!20, very thin];
\draw[help lines, step=1mm, very thin] (-10,-10) grid (10,10)
 [help lines, step=1cm, thin] (-10,-10) grid (10,10);


\pgfmoveto{\pgfpointxy{-1.3}{0}}
\pgfpathcurveto{\pgfpointxy{-3.3}{-5.3}}{\pgfpointxy{-.3}{-5.3}}{\pgfpointxy{0}{-5.3}}
\pgfpathcurveto{\pgfpointxy{.3}{-5.3}}{\pgfpointxy{3.3}{-5.3}}{\pgfpointxy{1.3}{0}}
\pgfpathcurveto{\pgfpointxy{3.3}{5.3}}{\pgfpointxy{.3}{5.3}}{\pgfpointxy{0}{5.3}}
\pgfpathcurveto{\pgfpointxy{-.3}{5.3}}{\pgfpointxy{-3.3}{5.3}}{\pgfpointxy{-1.3}{0}}
\pgfpathclose
\pgfsetstrokeopacity{0.5}
\pgfusepath{stroke}

\pgfmoveto{\pgfpointxy{-1}{0}}
\pgfpathcurveto{\pgfpointxy{-3}{-5}}{\pgfpointxy{-.1}{-5}}{\pgfpointxy{0}{-5}}
\pgfpathcurveto{\pgfpointxy{.1}{-5}}{\pgfpointxy{3}{-5}}{\pgfpointxy{1}{0}}
\pgfpathcurveto{\pgfpointxy{3}{5}}{\pgfpointxy{.1}{5}}{\pgfpointxy{0}{5}}
\pgfpathcurveto{\pgfpointxy{-.1}{5}}{\pgfpointxy{-3}{5}}{\pgfpointxy{-1}{0}}
\pgfpathclose
\pgfsetstrokeopacity{0.5}
\pgfusepath{stroke}

\foreach \y [remember=\y as \x (initially 0)] in {.1,.2,...,1} {
  \pgfpathcurvebetweentime{\x}{\y}{\pgfpointxy{-1.3}{0}}{\pgfpointxy{-3.3}{-5.3}}{\pgfpointxy{-.3}{-5.3}}{\pgfpointxy{0}{-5.3}}
 \pgfpathlineto{\pgfpointcurveattime{\y}{\pgfpointxy{-1}{0}}{\pgfpointxy{-3}{-5}}{\pgfpointxy{-.1}{-5}}{\pgfpointxy{0}{-5}}}
 \pgfpathcurvebetweentimecontinue{\y}{\x}{\pgfpointxy{-1}{0}}{\pgfpointxy{-3}{-5}}{\pgfpointxy{-.1}{-5}}{\pgfpointxy{0}{-5}}
 \pgfpathclose
 \pgfsetstrokeopacity{1}
 \pgfusepath{stroke}
};

\end{tikzpicture}
\end{document}

在此处输入图片描述

答案1

这里有一个建议,使用装饰来标记曲线上的点,然后循环连接它们。我使用 TikZ 级别的命令进行装饰,这与你使用的低级 PGF 命令略有不同;但我不知道低级等效命令是什么。

它之所以有效,是因为装饰会根据路径长度沿路径移动,而不是参数化(参数化不起作用,因为贝塞尔曲线不能保证按路径长度进行参数化)。由于已经有一个以间隔标记曲线的装饰,最简单的实现是在每条曲线上使用该装饰,然后将它们连接起来。

(如果您使用 TikZ 命令绘制实际曲线,则可以将曲线的整个绘制和标记位组合成单个绘制命令,并选择合适的后续操作。)

代码:

\documentclass{standalone}
%\url{http://tex.stackexchange.com/q/242016/86}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}
\begin{document}
\begin{tikzpicture}[scale=1]

\tikzstyle{help lines}=[blue!20, very thin];
\draw[help lines, step=1mm, very thin] (-10,-10) grid (10,10)
 [help lines, step=1cm, thin] (-10,-10) grid (10,10);


\pgfmoveto{\pgfpointxy{-1.3}{0}}
\pgfpathcurveto{\pgfpointxy{-3.3}{-5.3}}{\pgfpointxy{-.3}{-5.3}}{\pgfpointxy{0}{-5.3}}
\pgfpathcurveto{\pgfpointxy{.3}{-5.3}}{\pgfpointxy{3.3}{-5.3}}{\pgfpointxy{1.3}{0}}
\pgfpathcurveto{\pgfpointxy{3.3}{5.3}}{\pgfpointxy{.3}{5.3}}{\pgfpointxy{0}{5.3}}
\pgfpathcurveto{\pgfpointxy{-.3}{5.3}}{\pgfpointxy{-3.3}{5.3}}{\pgfpointxy{-1.3}{0}}
\pgfpathclose
\pgfsetstrokeopacity{0.5}
\pgfusepath{stroke}

\pgfmoveto{\pgfpointxy{-1}{0}}
\pgfpathcurveto{\pgfpointxy{-3}{-5}}{\pgfpointxy{-.1}{-5}}{\pgfpointxy{0}{-5}}
\pgfpathcurveto{\pgfpointxy{.1}{-5}}{\pgfpointxy{3}{-5}}{\pgfpointxy{1}{0}}
\pgfpathcurveto{\pgfpointxy{3}{5}}{\pgfpointxy{.1}{5}}{\pgfpointxy{0}{5}}
\pgfpathcurveto{\pgfpointxy{-.1}{5}}{\pgfpointxy{-3}{5}}{\pgfpointxy{-1}{0}}
\pgfpathclose
\pgfsetstrokeopacity{0.5}
\pgfusepath{stroke}

 \def\coordk{0}
 \draw[
   decorate,
   decoration={
     markings,
     mark=between positions 0 and 1 step .1 with
     {
       \coordinate (outer-\coordk) at (0,0);
       \pgfextra{\pgfmathtruncatemacro\coordk{\coordk+1}
       \global\let\coordk=\coordk}
     }
   }
 ]
 (-1.3,0) .. controls (-3.3,-5.3) and (-.3,-5.3) .. (0,-5.3);
\def\coordk{0}
 \draw[
   decorate,
   decoration={
     markings,
     mark=between positions 0 and 1 step .1 with
     {
       \coordinate (inner-\coordk) at (0,0);
       \pgfextra{\pgfmathtruncatemacro\coordk{\coordk+1}
       \global\let\coordk=\coordk}
     }
   }
 ]
 (-1,0) .. controls (-3,-5) and (-.1,-5) .. (0,-5);

 \foreach \y in {0,...,9} {
   \draw (outer-\y) -- (inner-\y);
 }
\end{tikzpicture}
\end{document}

结果:

明显的曲线

请注意,由于标记算法本身存在误差,有时它不会标记最终点,这就是我只迭代到第 9 个坐标的原因。不过,最终线段很容易放置到位,因此这并不是一个严重的问题。


编辑这是所有内容均使用 TikZ 级代码的版本。

\documentclass{standalone}
%\url{http://tex.stackexchange.com/q/242016/86}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}
\begin{document}
\begin{tikzpicture}

\tikzstyle{help lines}=[blue!20, very thin];
\draw[help lines, step=1mm, very thin] (-10,-10) grid (10,10)
 [help lines, step=1cm, thin] (-10,-10) grid (10,10);

 \def\coordk{0}
 \draw[
   postaction={
     decorate,
   },
   decoration={
     markings,
     mark=between positions 0 and 1 step .025 with
     {
       \coordinate (outer-\coordk) at (0,0);
       \pgfextra{\pgfmathtruncatemacro\coordk{\coordk+1}
       \global\let\coordk=\coordk}
     }
   }
 ]
 (-1.3,0)
 .. controls (-3.3,-5.3) and (-.3,-5.3) .. (0,-5.3)
 .. controls (.3,-5.3) and (3.3,-5.3) .. (1.3,0)
 .. controls (3.3,5.3) and (.3,5.3) .. (0,5.3)
 .. controls (-.3,5.3) and (-3.3,5.3) .. (-1.3,0);

 \def\coordk{0}
 \draw[
   postaction={
     decorate,
   },
   decoration={
     markings,
     mark=between positions 0 and 1 step .025 with
     {
       \coordinate (inner-\coordk) at (0,0);
       \pgfextra{\pgfmathtruncatemacro\coordk{\coordk+1}
       \global\let\coordk=\coordk}
     }
   },
   opacity=.5
 ]
 (-1,0)
 .. controls (-3,-5) and (-.1,-5) .. (0,-5)
 .. controls (.1,-5) and (3,-5) .. (1,0)
 .. controls (3,5) and (.1,5) .. (0,5)
 .. controls (-.1,5) and (-3,5) .. (-1,0);


 \foreach \y in {0,...,39} {
   \draw (outer-\y) -- (inner-\y);
 }
\end{tikzpicture}
\end{document}

结果:

上述内容的 TikZified 版本

相关内容