如何在计算三角形上绘制 tikz 箭头?

如何在计算三角形上绘制 tikz 箭头?

我需要很多矢量三角形,想用 来做TikZ。我的TikZ经验几乎不存在。因此,我想问您是否有可能用 来绘制计算矢量三角形(总和)TikZ

我需要的:

  • 三个不同颜色的矢量以三角形的形式指向一起
  • 可以通过“角-长-角”定义每个三角形
  • 也许可以隐藏其中一支或两支箭头。
  • 与每个向量中间对齐的中心标签(用于数学表达式)
  • 锚点 (0,0) 应该是c和的结合w
  • 矢量和应该是w + uu + w

我想获得速度三角形(用于机器中的体积流量)。最后,我会将它们定位在包含的图像上。因此,我需要三角形、单个矢量、圆弧矢量(旋转方向)和进入纸平面的矢量(圆圈中的十字 [进入纸面] 和圆圈中的点 [离开纸面]),它们看起来都应该相似且可识别。

在 内可以进行此类计算吗TIKZ?我应该选择其他包裹吗?如何获得与实际体积流量相匹配的简单技术速度三角形图?


一个样品:

在此处输入图片描述

\alpha\beta并且|u|应该由用户选择。其余部分是计算出来的。所选向量之间的角度定义也很好。例如:显示正向量和正向量之间的u角度w\beta

答案1

请参见修订 4了解 Op 的条件和给定的变量。

纸飞机矢量相对容易制作。如果你想给它们贴标签,我会使用带有自定义路径图片的节点。常用属性保存在 中。和paper plane vector的可选参数可用于更改标签。paper plane vector inpaper plane vector out

由于这两个三角形都很难概括,因此我创建了两种独特但相似的风格

  • vector triangle u+w
  • vector triangle w+u

两者都接受四个参数,以 分隔:。 (我同意,名称和参数都可以选择得更好。)这些参数是:

  1. 角度α
  2. 角度β
  3. 向量的长度
  4. 边缘节点的索引(它将被转发到边缘样式)。

还有其他样式

  • 角度标记@vector triangle angle(参数 4 和 5 是当两个角度位于同一点时的辅助参数)和三种附加样式
    • 为了dashed line
    • 对于arc line
    • 为了arc node;
  • every vector以及every vector node
  • 为每个向量和每个向量节点指定一个样式(例如C)。

样式dashed line处于无论如何都是矢量,或者当它与另一个角度的虚线相同时。

u+w样式中parallel marking,将被附加到dashed line并用于向量。该decorations.markings库就是为此使用的。

最后几种样式(参见代码中的注释)实际上不是必需的,因为它们是通过/.try处理程序访问的。如果没有它们,您将看到非常原始的绘图版本。

代码

\documentclass[tikz,convert=false]{standalone}
\colorlet{RED}{red!75!black}
\colorlet{BLACK}{black}
\colorlet{BLUE}{blue!75!black}
\usetikzlibrary{decorations.markings}
\makeatletter
\tikzset{edge node/.code={% stolen from the CVS version
    \expandafter\def\expandafter\tikz@tonodes\expandafter{\tikz@tonodes #1}}}
\makeatother
%% The paper plane vector things
\tikzset{
  paper plane vector/.style={
    shape=circle,
    inner sep=+0pt,
    minimum size=+1em,
    label={#1}
  },
  paper plane vector out/.style={
    paper plane vector={[RED]above left:{$#1$}},
    draw=RED,
    path picture={
      \fill[RED] (path picture bounding box.center) circle [radius=+1.41\pgflinewidth];
    }
  },
  paper plane vector in/.style={
    paper plane vector={[BLACK]above left:{$#1$}},
    draw=BLACK,
    path picture={
      \draw[BLACK] (path picture bounding box.south west) -- (path picture bounding box.north east)
                   (path picture bounding box.south east) -- (path picture bounding box.north west);
    }
  },
  paper plane vector in/.default=u,
  paper plane vector out/.default=w}

%% The parallel marking
\tikzset{
  parallel marking/.style={
    postaction={
      decoration={
        name=markings,
        mark=at position .33 with {\draw[solid,thin,-] (+-6\pgflinewidth,+-4\pgflinewidth) -- ++ (+8\pgflinewidth,+8\pgflinewidth)
                                                       (+-2\pgflinewidth,+-4\pgflinewidth) -- ++ (+8\pgflinewidth,+8\pgflinewidth); }
      },
      decorate}}}

%% The triangles, consisting only of an 'insert path'
\tikzset{
  vector triangle u+w/.style args={#1:#2:#3:#4}{% #1 = alpha,
                                                % #2 = beta,
                                                % #3 = length of w,
                                                % #4 = an argument that gets forwarded to the
                                                %      edges, here an index
    insert path={
       coordinate (vt@o)
       +({90+#2}:{#3}) coordinate (vt@c)
       {[dashed line/.append style=parallel marking, @vector triangle angle={vt@o}{#2}{\beta}{0}{0}]}
       {[dashed line/.style={draw=none},@vector triangle angle={vt@o}{#1}{\alpha}{.1}{#2}]}
       (intersection of vt@o--[shift={(90+#1:20)}] vt@o and vt@c--[shift={(down:20)}] vt@c) edge[u vector/.try={#4},parallel marking] (vt@c)
                                                                                            edge[c vector/.try={#4}] (vt@o)
                                                                                     (vt@c) edge[w vector/.try={#4}] (vt@o)
    }
  },
  vector triangle w+u/.style args={#1:#2:#3:#4}{% #1 = alpha,
                                                % #2 = beta,
                                                % #3 = length of w,
                                                % #4 = an argument that gets forwarded to the
                                                %      edges, here an index
    insert path={
       coordinate (vt@o)
       + ({90+#2-180}:{#3}) coordinate (vt@c)
       (intersection of vt@o--[shift={({#1-90}:20)}] vt@o and vt@c--[shift={(up:20)}] vt@c) coordinate (vt@aux)
       [@vector triangle angle={vt@aux}{#1}{\alpha}{0}{0}]
       {[dashed line/.style={draw=none},@vector triangle angle={vt@c}{#2}{\beta}{0}{0}]}
       (vt@o) edge[w vector/.try={#4}] (vt@c)
              edge[c vector/.try={#4}] (vt@aux)
       (vt@c) edge[u vector/.try={#4}] (vt@aux)
    }
  },
  %% The angle drawing, the arguments #4 and #5 are only for angles that overlap (see the u+w style why), usually the ary '0'
  @vector triangle angle/.style n args={5}{
    insert path={
      (#1) edge[dashed line/.try] ++ (up:1)
      ++(up:.75+#4) edge[arc line/.try, to path={arc [radius=.75+#4, start angle=90, delta angle={#2}]}] ()
      node [rotate={#5+(#2-#5)/2}, arc node/.try] at ([shift=({90+#5+(#2-#5)/2}:.5)] #1) {$#3$}}}}

%% A few presets for the vectors and nodes.
%% If these are not given, the drawing will still work (the '.try' handler takes care of that)
%% but you will have a raw version (try it!)
\tikzset{
  every vector/.style 2 args={shorten >=\pgflinewidth,->,edge node={node[#1 node/.try] {$\vec{#1}_{#2}$}}},
    w vector/.style={every vector={w}{#1},RED},
    u vector/.style={every vector={u}{#1},BLACK},
    c vector/.style={every vector={c}{#1},BLUE},
  every vector node/.style={below,sloped,text={#1}},
    w node/.style={every vector node=RED},
    u node/.style={every vector node=BLACK},
    c node/.style={every vector node=BLUE,above},
  dashed line/.style={thin, densely dotted, line cap=butt},
  arc line/.style={thin, solid, ->, line cap=butt, shorten >=.5\pgflinewidth, shorten <=.5\pgflinewidth},
  arc node/.style={font=\scriptsize},
}
\begin{document}
\begin{tikzpicture}[>=latex,line cap=round]
  \node[paper plane vector in] {};
  \node[paper plane vector out] at (-1,0) {};

  \path (-1,-2) [vector triangle w+u=105:45:4.5:1];

  \path (7,-3)  [vector triangle u+w=105:45:4.5:2];
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述


在此处输入图片描述

答案2

我画出了你的左边的三角形,你可以调整技巧来构建第二个三角形或任何其他三角形。

在底部,我解释了代码的作用。如果您需要进一步解释以便用它重新创建其他示例,请直接询问。

\documentclass[convert = false, border = 2cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc, intersections, arrows}

\begin{document}

\begin{tikzpicture}
  \coordinate (O) at (0, 0);

  \draw[-latex] (O) -- +(2, 0) coordinate (P1) node[pos = .5, above]
  {\(c_2\)};

  \path[name path = line1] (P1) -- +(0, -5);
  \path[name path = line2] (O) -- (-45:4cm);
  \path[name intersections = {of = line1 and line2, by = P2}];

  \draw[-latex, red] (O) -- (P2) node[pos = .5, below] {\(w_1\)};
  \draw[-latex] (P2) -- (P1) node[pos = .5, right] {\(v_1\)};

  \draw[shorten >=.5\pgflinewidth, shorten <=.5\pgflinewidth, -latex, red] 
  let
    \p0 = (P2),
    \p1 = (P1),
    \p2 = (O),
    \n1 = {atan2(\x1 - \x0, \y1 - \y0)},
    \n2 = {atan2(\x2 - \x0, \y2 - \y0)},
    \n3 = {1cm},
    \n4 = {(\n1 + \n2) / 2}
  in (P2) -- +(\n1:\n3) arc[radius = \n3, start angle = \n1, end angle = \n2]
  node at ([shift = (P2)] \n4:.5cm) {\(\alpha_1\)};
\end{tikzpicture}

\end{document}

我首先将原点标记为(O)。从 开始(O),我们可以使用 来-- +()指定与原点的距离。在这个例子中,我说了20然后我将向量的末端标记为(P1)

接下来,我使用路径命令绘制一条直线,(P1)以及一条具有极坐标-45度和半径的线4cm。如您所见,我将这两条线命名为intersections库中使用的名称。

利用这个intersections库,我找到了两条路径的交点,并标记了它(P2)。现在,我们有一个坐标,可以用其他向量来指引起点和终点。

最后,我使用\draw let .. in命令来找到角度并在两个向量之间绘制圆弧。

正如 Qrrbrbirlbel 所建议的,我们不需要on background layer如果我们添加\draw[shorten >=.5\pgflinewidth, shorten <=.5\pgflinewidth, -latex, red]

在此处输入图片描述

为了在您编辑的帖子中创建第一个三角形,我需要做的就是更改:

  \coordinate (O) at (0, 0);

  \begin{pgfinterruptboundingbox}
    \path[name path = line1] (O) -- (15:7cm);

    \draw[-latex, red] (O) -- (-45:4.5cm) coordinate (P1) node[pos = .5,
    below left, rotate = -45]
    {\(\mathbf{w}\)};

    \path[name path = line2] (P1) -- +(0, 7cm);
    \path[name intersections = {of = line1 and line2, by = P2}];
  \end{pgfinterruptboundingbox}   

  \draw[-latex, blue] (O) -- (P2) node[pos = .5, above, rotate = 15] {\(\mathbf{c}\)};
  \draw[-latex] (P1) -- (P2) node[pos = .5, right] {\(\mathbf{u}\)};
  \draw[dashed] (P2) -- +(0, 1.5cm) coordinate (P3);

  \draw[-latex] let
    \p0 = (P2),
    \p1 = (P3),
    \p2 = (O),
    \n1 = {atan2(\x1 - \x0, \y1 - \y0) - 360},
    \n2 = {atan2(\x2 - \x0, \y2 - \y0)},
    \n3 = {.75cm},
    \n4 = {(\n1 + \n2) / 2}
  in (P2) +(\n1:\n3) arc[radius = \n3, start angle = \n1, end angle = \n2]
  node at ([shift = (P2)] \n4:.5cm) {\(\alpha\)};

  \draw[-latex] let
    \p0 = (P1),
    \p1 = (P2),
    \p2 = (O),
    \n1 = {atan2((\x1 - \x0) / (\y1 - \y0), 1)}, %see link for explanation here
    \n2 = {atan2(\x2 - \x0, \y2 - \y0)},
    \n3 = {.75cm},
    \n4 = {(\n1 + \n2) / 2}
  in (P1) +(\n1:\n3) arc[radius = \n3, start angle = \n1, end angle = \n2]
  node at ([shift = (P1)] \n4:.5cm) {\(\beta\)};

第二个命令出错了\draw let .. in,所以我问了一个问题。你可以在这里阅读详细信息TikZ:当我使用 draw let ... in 命令绘制一个简单的圆弧时,我得到的尺寸太大以及为什么\n1在这种情况下会有所不同。

在此处输入图片描述

有了TikZ,我们可以使用数学解析器来计算角度。因此,我们可以验证所有内容是否完全符合绘图规范。

\documentclass[convert = false, border = 1cm]{standalone}
\usepackage{tikz, fp}
\usetikzlibrary{calc, intersections, arrows, fixedpointarithmetic}

\begin{document}
\begin{tikzpicture}[fixed point arithmetic]
\coordinate (O) at (0, 0);

\begin{pgfinterruptboundingbox}
  \path[name path = line1] (O) -- (15:7cm);

  \draw[-latex, red] (O) -- (-45:4.5cm) coordinate (P1) node[pos =   .5,
  below left, rotate = -45]
  {\(\mathbf{w}\)};

  \path[name path = line2] (P1) -- +(0, 7cm);
  \path[name intersections = {of = line1 and line2, by = P2}];
\end{pgfinterruptboundingbox}

\draw[-latex, blue] (O) -- (P2) node[pos = .5, above, rotate = 15]
{\(\mathbf{c}\)};
\draw[-latex] (P1) -- (P2) node[pos = .5, right] {\(\mathbf{u}\)};
\draw[dashed] (P2) -- +(0, 1.5cm) coordinate (P3);

\draw[-latex] let
\p0 = (P2),
\p1 = (P3),
\p2 = (O),
\n1 = {atan2(\x1 - \x0, \y1 - \y0) - 360},
\n2 = {atan2(\x2 - \x0, \y2 - \y0)},
\n3 = {.75cm},
\n4 = {(\n1 + \n2) / 2}
in (P2) +(\n1:\n3) arc[radius = \n3, start angle = \n1, end angle = \n2]
node at ([shift = (P2)] \n4:.5cm) {\(\alpha\)} node[above] at
([shift = (P2)] \n4:\n3) {\pgfmathparse{\n2 - \n1}%                                 
  $\pgfmathprintnumber{\pgfmathresult}^{\circ}$
};

\draw[-latex] let
\p0 = (P1),
\p1 = (P2),
\p2 = (O),
\n1 = {atan2((\x1 - \x0) / (\y1 - \y0), 1)}, %see link for explanation here         
\n2 = {atan2(\x2 - \x0, \y2 - \y0)},
\n3 = {.75cm},
\n4 = {(\n1 + \n2) / 2}
in (P1) +(\n1:\n3) arc[radius = \n3, start angle = \n1, end angle = \n2]
node at ([shift = (P1)] \n4:.5cm) {\(\beta\)} node[above] at
([shift = (P1)] \n4:\n3) {\pgfmathparse{\n2 - \n1}%                                 
  $\pgfmathprintnumber{\pgfmathresult}^{\circ}$
};
\end{tikzpicture}
\end{document}

在此处输入图片描述

根据 LaRiFaRi 的评论,如果您更改

\draw[-latex, red] (O) -- (0:4.5cm) coordinate (P1) node[pos =   .5,
    below left, rotate = 0]
    {\(\mathbf{w}\)};

在此处输入图片描述

答案3

我认为所有这些都可以通过 tikz 实现(\usetikzlibrary{calc,intersections}至少)。

这里有一个简单的例子,其中的宏需要 2 个参数(相对坐标 - 极坐标或笛卡尔坐标 - 随便你选择)和一个​​可选的第 3 个参数,该参数应该是三角形起点的绝对坐标(默认为 (0,0))。

\documentclass{article}
\usepackage{tikz}
%\usetikzlibrary{calc}%,intersections}
\begin{document}

\newcommand{\TR}[3][0,0]{
\coordinate(E0) at (#1);
\draw[-latex](#1)--+(#2)coordinate(E1)node[pos=0.5,sloped](M0){};\coordinate(M0)at(M0);
\draw[-latex](E1)--+(#3)coordinate(E2)node[pos=0.5,sloped](M1){};\coordinate(M1)at(M1);
\draw[-latex](E2)--(E0)node[pos=0.5,sloped](M2){};\coordinate(M2)at(M2);
}

\begin{tikzpicture}
\TR{10:5}{100:3}
%\TR[10:5]{20:3}{110:8}
\draw(M2)circle(5pt);
\filldraw[green](E0)circle(5pt);

\TR[M0]{270:1}{30:2}
\TR[M1]{270:1}{30:2}%Using mid of old triangle for starting point of new triangle
\TR[M1]{270:1}{30:2}
\TR[M1]{270:1}{30:2}
%\TR[M2]{20:3}{110:8}
\end{tikzpicture}
\end{document}

在此处输入图片描述

这只是基本的 tikz 内容 - 更高级的计算是用 calc 完成的,例如:

($0.5*(A)+0.5*(B)$)

计算(笛卡尔)坐标 A 和 B 的中心点。

也可以进行预测

($(A)!(C)!(B)$)

像这样。

有关计算的更多信息,请参见:可用的 TikZ 库列表及简短介绍

可以通过使用宏中的某些样式并在调用宏之前更改这些样式来隐藏箭头。

但要注意 - 如果编写不正确,复杂的宏会使事情更难阅读,也更难维护(即使这样也会变得乏味)。

相关内容