存储和重新使用 tikz 坐标作为位置和切向量

存储和重新使用 tikz 坐标作为位置和切向量

下面的代码

\documentclass[border=5pt]{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.11}
\usetikzlibrary{arrows,backgrounds,patterns,shapes.geometric,calc,positioning}
\tikzset{small dot/.style={fill=black,circle,outer sep=8pt,scale=0.25}}

\begin{document}

\begin{tikzpicture}[scale=0.8]
    \draw[ultra thin,color=lightgray] (-4,-2) grid (7,5);   % coordinate grid
    \draw[<->] (-4.5,0) -- (7.5,0) node[right] {$x$};   % x-axis
    \draw[<->] (0,-2.5) -- (0,5.5) node[above] {$y$};   % y-axis

    \foreach \x/\xtext in {-4,...,-1,1,2,..., 7}        % x-axis labels
        \draw (\x cm,2pt) -- (\x cm,-2pt) node[anchor=north, font=\footnotesize] {$\xtext$}; 

    \foreach \y/\ytext in {-2, -1,1,2,..., 5}           % y-axis labels
        \draw (2pt,\y cm) -- (-2pt,\y cm) node[anchor=east, font=\footnotesize] {$\ytext$}; 

    % parametric function alpha(t)
        \draw [thick, samples=1000] plot[parametric, domain=0:2*pi, id=spiral] function{t*cos(t),-t*sin(t)};

    % points on graph
    \foreach \t in {0, 30, ..., 360}
        \filldraw ({(\t*3.14/180)*cos(\t)},{-(\t*3.14/180)*sin(\t)}) circle (2pt);

    % position vectors
    \foreach \t in {0, 30, ..., 360}
        \draw[->, color=blue, thin] (0,0) -- 
            ({(\t*3.1/180)*cos(\t)},{-(\t*3.1/180)*sin(\t)});

    %tangent vectors
    \foreach \t in {0, 30, ..., 360}
        \draw[->, color=red, dashed, very thin] ({(\t*3.14/180)*cos(\t)},{-(\t*3.14/180)*sin(\t)}) --
        +({-(\t*3.14/180)*sin(\t) + cos(\t)}, {-(\t*3.14/180)*cos(\t) - sin(\t)});

\end{tikzpicture}
\end{document}

产生我目前需要的东西:

带位置和切向量的螺旋线

我正在生成一条参数曲线,然后在各个点绘制位置和切向量。我已经读完了, 和,特别是,对相关问题的回答非常有帮助。我仍然有几个关于如何更有效地做到这一点的问题。

首先,有没有办法存储曲线上各个点的坐标,然后重新使用这些坐标来创建位置和切向量?例如,我想计算并存储类似

\foreach \t in {0, 0.5236, ..., 6.28}
    \x = {x(t)}
    \y = {y(t)}

在一个数组中,其中x(t)y(t)是位置函数。然后我将使用这些存储的值来创建位置向量,如下所示

\for each (\x, \y) in [position array]
    \draw[->, color=blue, thin] (0,0) -- (\x,\y);

类似地,对于速度矢量,我将计算

\foreach \t in {0, 0.5236, ..., 6.28}
    \deltax = {x'(t)}
    \deltay = {y'(t)}

并创建速度矢量

\for each (\x, \y) in [position array]
    \draw[->, color=blue, thin] (\x,\y) -- + (\deltax, \deltay);

其中,(\deltax,\deltay)被索引以与适当的位置向量匹配(\x,\y)

我已经读过 pgf / tikz 将 gnuplot 坐标存储在 .table 文件中,但我不知道如何访问它们来执行此操作。

其次,我发现cos(\t)sin(\t)使用的是\t度数,所以我必须手动将矢量的大小转换为弧度。有没有更好的方法来做到这一点?代码

\foreach \t in {0, 30, ..., 360}
\pgfmathparse{rad(\t)}
\draw[->, color=blue, very thin] (0,0) -- 
    ({\pgfmathresult*cos(\t)},{-\pgfmathresult*sin(\t)});

不起作用。

答案1

这是一个解决方案:

  • (f-\t)是曲线上的一个点,

  • (f'-\t)是关联的切向量。

\documentclass[border=5pt]{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
  \draw[ultra thin,color=lightgray] (-4,-2) grid (7,5);   % coordinate grid
  \draw[<->] (-4.5,0) -- (7.5,0) node[right] {$x$};   % x-axis
  \draw[<->] (0,-2.5) -- (0,5.5) node[above] {$y$};   % y-axis

  \foreach \x/\xtext in {-4,...,-1,1,2,...,7}        % x-axis labels
  \draw (\x,2pt) -- (\x,-2pt) node[anchor=north, font=\footnotesize] {$\xtext$}; 

  \foreach \y/\ytext in {-2, -1,1,2,..., 5}           % y-axis labels
  \draw (2pt,\y) -- (-2pt,\y) node[anchor=east, font=\footnotesize] {$\ytext$}; 

  % parametric function alpha(t)
  \draw [thick, samples=50,smooth] plot[variable=\t, domain=0:2*pi] ({\t*cos(\t r)},{-\t*sin(\t r)});

  % points and tangent
  \foreach \t in {0, 30, ..., 360}{
    \pgfmathsetmacro\radius{rad(\t)}
    \pgfmathsetmacro\st{sin(\t)}
    \pgfmathsetmacro\ct{cos(\t)}
    \path
    ({\radius*\ct},{-\radius*\st}) coordinate (f-\t)
    ({-\radius*\st+\ct},{-\radius*\ct-\st}) coordinate (f'-\t);
  }

  % draw points, radii and vectors
  \foreach \t in {0,30,...,360}{
    \fill (f-\t) circle (2pt);
    \draw[->, color=blue, thin] (0,0) -- (f-\t);
    \draw[->, color=red, dashed, very thin] (f-\t) -- ++(f'-\t);
  }
\end{tikzpicture}
\end{document}

编辑

这是一个使用 TikZ 库的变体math,其中每个点都由其顺序号而不是其角度位置命名。

在此处输入图片描述

\documentclass[border=5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{math}
\begin{document}
\begin{tikzpicture}
  \draw[ultra thin,color=lightgray] (-4,-2) grid (7,5);   % coordinate grid
  \draw[<->] (-4.5,0) -- (7.5,0) node[right] {$x$};   % x-axis
  \draw[<->] (0,-2.5) -- (0,5.5) node[above] {$y$};   % y-axis

  \foreach \x/\xtext in {-4,...,-1,1,2,...,7}        % x-axis labels
  \draw (\x,2pt) -- (\x,-2pt) node[anchor=north, font=\footnotesize] {$\xtext$}; 

  \foreach \y/\ytext in {-2, -1,1,2,..., 5}           % y-axis labels
  \draw (2pt,\y) -- (-2pt,\y) node[anchor=east, font=\footnotesize] {$\ytext$}; 

  % parametric function alpha(t)
  \draw [thick, samples=50,smooth] plot[variable=\t, domain=0:2*pi] ({\t*cos(\t r)},{-\t*sin(\t r)});

  % points and tangent
  \tikzmath{
    integer \c; \c = 0;
    for \t in {30,60,...,360}{
      \c = \c + 1;
      \radius = rad(\t);
      \st = sin(\t);
      \ct = cos(\t);
      {
        \path
        ({\radius*\ct},{-\radius*\st}) coordinate (f-\c)
        ({-\radius*\st+\ct},{-\radius*\ct-\st}) coordinate (f'-\c);
      };
    };
  }

  % draw points, radii and vectors
  \foreach \c in {1,...,12}{
    \draw[->, color=blue, thin] (0,0) -- (f-\c);
    \draw[->, color=red, dashed, very thin] (f-\c) -- ++(f'-\c);
    \path (f-\c) node[text=white,circle,minimum size=8pt,inner sep=0,fill=black,font=\tiny]{\c};
  }
\end{tikzpicture}
\end{document}

答案2

除了缺少的 gnuplot 文件外,其余都是有效的:

\documentclass[border=5pt]{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.12}
\usetikzlibrary{arrows,backgrounds,patterns,shapes.geometric,calc,positioning}
\tikzset{small dot/.style={fill=black,circle,outer sep=8pt,scale=0.25}}

\begin{document}

\begin{tikzpicture}[scale=0.8]
    \draw[ultra thin,color=lightgray] (-4,-2) grid (7,5);   % coordinate grid
    \draw[<->] (-4.5,0) -- (7.5,0) node[right] {$x$};   % x-axis
    \draw[<->] (0,-2.5) -- (0,5.5) node[above] {$y$};   % y-axis

    \foreach \x/\xtext in {-4,...,-1,1,2,..., 7}        % x-axis labels
        \draw (\x cm,2pt) -- (\x cm,-2pt) node[anchor=north, font=\footnotesize] {$\xtext$}; 

    \foreach \y/\ytext in {-2, -1,1,2,..., 5}           % y-axis labels
        \draw (2pt,\y cm) -- (-2pt,\y cm) node[anchor=east, font=\footnotesize] {$\ytext$}; 

    % parametric function alpha(t)
    \draw [thick, samples=1000] plot[parametric, domain=0:2*pi, id=spiral] function{t*cos(t),-t*sin(t)};

    % points on graph
    \foreach \t in {0, 30, ..., 360}
        {\pgfmathparse{\t*3.141592653589793/180}
        \let\radius=\pgfmathresult
        \coordinate (P\t) at ({\radius*cos(\t)},{-\radius*sin(\t)});
        \filldraw (P\t) circle (2pt);}

    % position vectors
    \foreach \t in {0, 30, ..., 360}
        \draw[->, color=blue, thin] (0,0) -- (P\t);

    %tangent vectors
    \foreach \t in {0, 30, ..., 360}
        \draw[->, color=red, dashed, very thin] (P\t) -- +($(0,0)!1!-90:(P\t) + ({cos(\t)},{-sin(\t)})$);}
\end{tikzpicture}
\end{document}

答案3

这里介绍一种使用循环evaluate选项的方法foreach。使用这种方法,您可以在一个循环中创建整个图并预先计算所有需要的值。

图上的坐标通过 保存coord-\x并可重复使用。所有计算均通过 完成evaluate

我认为代码非常直观。如果您还有疑问,请随时提问。

\documentclass[tikz, border=6mm]{standalone}

\begin{document}
  \begin{tikzpicture}[>=latex]
    % Axis
    \draw [black!25, thin] (-4,-2) grid (7,5);
    \draw [<->] (-4.5,0) -- (7.5,0) node [right] {$x$};
    \draw [<->] (0,-2.5) -- (0,5.5) node [above] {$y$};
    \foreach \x in {-4,...,-1,1,2,...,7} {
        \draw (\x,2pt) -- (\x,-2pt) node [below] {$\x$};
        \ifnum\x>-3\ifnum\x<6
            \draw (-2pt,\x) -- (2pt,\x) node [left=.25cm] {$\x$};
        \fi\fi
    }

    % Plot
    \draw [thick, smooth, domain=0:2*pi] plot ({\x*cos(\x r)}, {-\x*sin(\x r)});
    \foreach \x [
        evaluate=\x as \rx using \x*pi/180, %
        evaluate=\rx as \rsin using \rx*sin(\x), %
        evaluate=\rx as \rcos using \rx*cos(\x), %
        evaluate=\x as \sin using sin(\x), %
        evaluate=\x as \cos using cos(\x)] in {30, 60,...,360} {
            \fill (\rcos, -\rsin) circle (2pt) coordinate (coord-\x);
            \draw [blue, ->] (0,0) -- (coord-\x);
            \draw [red, dashed, ->] (coord-\x) -- +({-\rsin+\cos}, {-\rcos-\sin});
    }
    \fill [blue] (0,0) circle (2pt);
  \end{tikzpicture}
\end{document}

渲染图像

答案4

另一个使用该math库的示例。这说明了运算符的用法,r该运算符是将前一个数字转换为度数的后缀运算符。此外,点和导数存储为坐标宏。

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{math}
\tikzmath{
  coordinate \c, \d;
  integer \n;
  \n = 0;
  for \t in {0, pi/6, ..., 2*pi}{
    \n = \n + 1;
    \a = \t r;
    \c{\n} = (\t * cos \a, -\t * sin \a); 
    \d{\n} = (cos \a - \t * sin \a, -sin \a - \t * cos \a); 
  };
} 
\begin{document}
\begin{tikzpicture}[>=stealth]
\draw [ultra thin, color=lightgray] (-4,-2) grid (7,5); 
\draw [<->] (-4.5,0) -- (7.5,0) node[right] {$x$};
\draw [<->] (0,-2.5) -- (0,5.5) node[above] {$y$};
\foreach \x/\xtext in {-4, -3, ..., 7}
  \draw (\x,2pt) -- (\x,-2pt) node [anchor=north, font=\footnotesize] {$\xtext$}; 
\foreach \y/\ytext in {-2, -1, ..., 5} 
  \draw (2pt,\y) -- (-2pt,\y) node [anchor=east, font=\footnotesize] {$\ytext$}; 

\draw [thick, samples=250] plot [smooth, domain=0:2*pi, variable=\t] 
  ({\t*cos(\t r)},{-\t*sin(\t r)});
\foreach \i in {2,...,\n}{
  \draw [blue, shorten >=2pt, ->] (0, 0) -- (\c{\i});
  \draw [red, dashed, ->]  (\c{\i}) -- (\cx{\i}+\dx{\i}, \cy{\i}+\dy{\i});
  \fill (\c{\i}) circle [radius=2pt];
}
\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容