TikZ:使用 draw let 语法创建圆弧,但圆弧及其差角之和不等于 360 度

TikZ:使用 draw let 语法创建圆弧,但圆弧及其差角之和不等于 360 度

考虑以下代码片段:

\draw[-latex] let
        \p0 = (P6),
        \p1 = (P5),
        \p2 = (P4),
        \n1 = {atan2(\x1 - \x0, \y1 - \y0)},
        \n2 = {atan2(\x2 - \x0, \y2 - \y0)},
        \n3 = {.75cm},
        \n4 = {(\n2 + \n1) / 2}
      in (P6) +(\n1:\n3) arc[radius = \n3, start angle = \n1, end angle = \n2];

这来自下面的代码(在底部):

\documentclass[convert = false]{standalone}

\usepackage{tikz}
\usetikzlibrary{calc, intersections, backgrounds, arrows}

\begin{document}

\tikzset{circle with radius/.style = {shape = circle, inner sep = 0pt,
      outer sep = 0pt, minimum size = {2 * (#1)}}}
  \begin{tikzpicture}[line join = round, line cap = round,
    every label/.append style = {font = \scriptsize},
    dot/.style = {inner sep = +0pt, shape = circle,
      draw = black, label = {#1}},
    small dot/.style = {minimum size = .05cm, dot = {#1}},
    big dot/.style = {minimum size = .1cm, dot = {#1}},
    ]
    \begin{scope}
      %\clip ($(B) + (1.5, -2)$) rectangle ($(B) + (-3, 2)$);                       

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

      \pgfmathsetmacro{\as}{3}
      \pgfmathsetmacro{\bs}{2.25}
      \pgfmathsetmacro{\c}{sqrt(\as^2 - \bs^2)}
      \pgfmathsetmacro{\al}{3.75}
      \pgfmathsetmacro{\bl}{2.9}
      \pgfmathsetmacro{\cl}{sqrt(\al^2 - \bl^2)}
      \pgfmathsetmacro{\xs}{abs(\c - \cl)}

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

      \node[fill = black, big dot = {below left: \(F\)}] (F) at (\c, 0) {};

      \path[name path global = line1] (\c, 0) -- ++(60:{\as} and \bs);
      \path[name path global = line2] (\c, 0) -- ++(150:6cm);
    
    \draw[name path global = ell1, blue] (O) ellipse
        (\as cm and \bs cm);

        \draw[name path global = ell2, red] (-\xs, 0)
        ellipse (\al cm and \bl cm);

      \path[name intersections = {of = line1 and ell1, by = P1}];
      \node[fill = black, big dot = {right: \(A\)}] (A) at (P1) {};

      \path[name intersections = {of = line2 and ell2, by = P2}];
      \node[fill = black, big dot = {above: \(B\)}] (B) at (P2) {};

      \begin{scope}[declare function = {doubleA = 5.8cm;},
        ]
        \clip ($(A.center) + (1, 0)$) rectangle ($(B.center) + (0, 1)$);
        \begin{pgfinterruptboundingbox}
          \path let
            \p1 = ($(A) - (F)$),
            \p2 = ($(B) - (F)$),
            \n1 = {veclen(\x1, \y1)},
            \n2 = {veclen(\x2, \y2)}
          in
          (A) node[name path global = aCircle, circle with radius = doubleA-\n1]
          {}
          (B) node[name path global = bCircle, circle with radius = doubleA-\n2]
          {}
          (F) node[name path global = fCircle,
          circle with radius = .5 * doubleA] {};

          \tikzset{name intersections = {of = aCircle and bCircle, name = F'} }
          \foreach \solA in {2} {
            \path ($(F)!.5!(F'-\solA)$) coordinate (C'-\solA)
            ($(C'-\solA)!doubleA/2!(F)$) coordinate (xDir-\solA)
            (F'-\solA) node[name path global/.expanded = f'Circle-\solA,
            circle with radius = .5 * doubleA] {};
          }                         %!?      
          \foreach \solA in {2} { %!?                                               
            \path[name intersections = {of = fCircle and f'Circle-\solA,
              by = {yDir-\solA}}]
            ($(xDir-\solA)-(C'-\solA)$) coordinate (xDir'-\solA)
            ($(yDir-\solA)-(C'-\solA)$) coordinate (yDir'-\solA)
            ;
          }
        \end{pgfinterruptboundingbox}
        \foreach \solA in {2}
        \draw[x = (xDir'-\solA), y = (yDir'-\solA), name path global = traj]
        (C'-\solA) circle [radius = 1];
      \end{scope}

      \path[name path = circ] (B) circle [radius = 1bp];

      \draw[name intersections = {of = circ and traj}, -latex] (B) --
      ($(intersection-1)!1.25cm!(intersection-2)$) coordinate (P3);
      \draw[name intersections = {of = circ and ell2}, -latex, red] (B) --
      ($(intersection-1)!2cm!(intersection-2)$) coordinate (P4);
      \draw[-latex, name path = line3] (P3) -- (P4);
      \draw[name path = line4] (B) -- ($(B)!2.1cm!-90:(F)$) coordinate (P5);

      \path[name path = circ2] (P3) circle [radius = 1bp];
      \path[name intersections = {of = circ2 and line3}, name path = line5]
      (P3) -- ($(intersection-1)!2cm!(P3)$);
      \path[name intersections = {of = line5 and line4, by = P6}];

      \path[name intersections = {of = circ and traj}] (B) --
      ($(intersection-1)!1.5cm!(intersection-2)$) coordinate (P7);

      \path[name intersections = {of = circ and ell2}] (B) --
      ($(intersection-1)!2.5cm!(intersection-2)$) coordinate (P8);
      
      \draw[-latex] let
        \p0 = (P6),
        \p1 = (P5),
        \p2 = (P4),
        \n1 = {atan2(\x1 - \x0, \y1 - \y0)},
        \n2 = {atan2(\x2 - \x0, \y2 - \y0)},
        \n3 = {.75cm},
        \n4 = {(\n2 + \n1) / 2}
      in (P6) +(\n1:\n3) arc[radius = \n3, start angle = \n1, end angle = \n2];
    \end{scope}
  \end{tikzpicture}

\end{document}

因此,在这个绘制命令中,我将第 0 个点设置为焦点,第 1 个点设置为起始角度线,第 2 个点设置为终止角度线。但是,TikZ 图片的弧线方向相反(见下文):

在此处输入图片描述

因此我随后采取了\n2 = {2 * pi - atan2(..)}应该是楔形而不是用弧线包围的方法来生成此图片:

在此处输入图片描述

从理论上讲,这两个圆弧应该加起来形成一个完整的圆。

出了什么问题?

我怎样才能让命令以正确的距离成弧?

如果我编译这两个命令,我们可以毫无疑问地看到它们不相符:

在此处输入图片描述


编辑2:

请考虑下面的图片:

在此处输入图片描述

至于为什么我将上面的代码用作 MWE,我们可以看到,我在同一区域内也有一些具有负角度的圆弧。我定义这些圆弧的方式与定义造成问题的圆弧的方式相同。因此,这似乎是该区域的问题,而不是负角度的问题。

例如,gamma2 被定义为焦点、下线和上线,但它绘制圆弧而不需要特殊处理,这与我在这里询问的 phi 角不同。

答案1

PGF 中的三角函数使用度数,因此您必须使用360而不是2*pi,并且必须从角度中减去整个圆,而不是相反。

如果您举一个简单的例子并查看角度,这一点就会变得清晰起来。delta angle弧的 是end angle减去start angle。在您的例子中,您的增量角大于 180°,因此您得到了较大的弧。通过从结束角度中减去一个完整的圆,差角的绝对值变得小于 180°:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}
\coordinate [label=right:O] (O) at (0,0);
\coordinate [label=below:A] (A) at (-1,-1.5);
\coordinate [label=left:B] (B) at (-2,1);
\draw (A) -- (O) -- (B);

\draw [-latex] 
    let
        \p0 = (O),
        \p1 = (A),
        \p2 = (B),
        \n1 = {atan2(\x1 - \x0, \y1 - \y0)},
        \n2 = {atan2(\x2 - \x0, \y2 - \y0)},
        \n3 = {1cm}
    in
        (\p0) + (\n1:\n3) arc [radius=\n3, start angle=\n1, end angle=\n2]
    node [anchor=west, align=right] at (1.5,0) {\verb|\n1|: \pgfmathparse{\n1}\pgfmathprintnumber{\pgfmathresult}\\ \verb|\n2|: \pgfmathparse{\n2}\pgfmathprintnumber{\pgfmathresult}\\
    delta: \pgfmathparse{\n2-\n1}\pgfmathprintnumber{\pgfmathresult}};
\end{tikzpicture}

\begin{tikzpicture}
\coordinate [label=right:O] (O) at (0,0);
\coordinate [label=below:A] (A) at (-1,-1.5);
\coordinate [label=left:B] (B) at (-2,1);
\draw (A) -- (O) -- (B);

\draw [-latex] 
    let
        \p0 = (O),
        \p1 = (A),
        \p2 = (B),
        \n1 = {atan2(\x1 - \x0, \y1 - \y0)},
        \n2 = {atan2(\x2 - \x0, \y2 - \y0) - 360},
        \n3 = {1cm}
    in
        (\p0) + (\n1:\n3) arc [radius=\n3, start angle=\n1, end angle=\n2]
    node [anchor=west, align=right] at (1.5,0) {\verb|\n1|: \pgfmathparse{\n1}\pgfmathprintnumber{\pgfmathresult}\\ \verb|\n2|: \pgfmathparse{\n2}\pgfmathprintnumber{\pgfmathresult}\\
    delta: \pgfmathparse{\n2-\n1}\pgfmathprintnumber{\pgfmathresult}};
\end{tikzpicture}


\end{document}

\documentclass[convert = false]{standalone}

\usepackage{tikz}
\usetikzlibrary{calc, intersections, backgrounds, arrows}

\begin{document}

\tikzset{circle with radius/.style = {shape = circle, inner sep = 0pt,
      outer sep = 0pt, minimum size = {2 * (#1)}}}
  \begin{tikzpicture}[line join = round, line cap = round,
    every label/.append style = {font = \scriptsize},
    dot/.style = {inner sep = +0pt, shape = circle,
      draw = black, label = {#1}},
    small dot/.style = {minimum size = .05cm, dot = {#1}},
    big dot/.style = {minimum size = .1cm, dot = {#1}},
    ]
    \begin{scope}
      %\clip ($(B) + (1.5, -2)$) rectangle ($(B) + (-3, 2)$);                       

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

      \pgfmathsetmacro{\as}{3}
      \pgfmathsetmacro{\bs}{2.25}
      \pgfmathsetmacro{\c}{sqrt(\as^2 - \bs^2)}
      \pgfmathsetmacro{\al}{3.75}
      \pgfmathsetmacro{\bl}{2.9}
      \pgfmathsetmacro{\cl}{sqrt(\al^2 - \bl^2)}
      \pgfmathsetmacro{\xs}{abs(\c - \cl)}

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

      \node[fill = black, big dot = {below left: \(F\)}] (F) at (\c, 0) {};

      \path[name path global = line1] (\c, 0) -- ++(60:{\as} and \bs);
      \path[name path global = line2] (\c, 0) -- ++(150:6cm);

    \draw[name path global = ell1, blue] (O) ellipse
        (\as cm and \bs cm);

        \draw[name path global = ell2, red] (-\xs, 0)
        ellipse (\al cm and \bl cm);

      \path[name intersections = {of = line1 and ell1, by = P1}];
      \node[fill = black, big dot = {right: \(A\)}] (A) at (P1) {};

      \path[name intersections = {of = line2 and ell2, by = P2}];
      \node[fill = black, big dot = {above: \(B\)}] (B) at (P2) {};

      \begin{scope}[declare function = {doubleA = 5.8cm;},
        ]
        \clip ($(A.center) + (1, 0)$) rectangle ($(B.center) + (0, 1)$);
        \begin{pgfinterruptboundingbox}
          \path let
            \p1 = ($(A) - (F)$),
            \p2 = ($(B) - (F)$),
            \n1 = {veclen(\x1, \y1)},
            \n2 = {veclen(\x2, \y2)}
          in
          (A) node[name path global = aCircle, circle with radius = doubleA-\n1]
          {}
          (B) node[name path global = bCircle, circle with radius = doubleA-\n2]
          {}
          (F) node[name path global = fCircle,
          circle with radius = .5 * doubleA] {};

          \tikzset{name intersections = {of = aCircle and bCircle, name = F'} }
          \foreach \solA in {2} {
            \path ($(F)!.5!(F'-\solA)$) coordinate (C'-\solA)
            ($(C'-\solA)!doubleA/2!(F)$) coordinate (xDir-\solA)
            (F'-\solA) node[name path global/.expanded = f'Circle-\solA,
            circle with radius = .5 * doubleA] {};
          }                         %!?      
          \foreach \solA in {2} { %!?                                               
            \path[name intersections = {of = fCircle and f'Circle-\solA,
              by = {yDir-\solA}}]
            ($(xDir-\solA)-(C'-\solA)$) coordinate (xDir'-\solA)
            ($(yDir-\solA)-(C'-\solA)$) coordinate (yDir'-\solA)
            ;
          }
        \end{pgfinterruptboundingbox}
        \foreach \solA in {2}
        \draw[x = (xDir'-\solA), y = (yDir'-\solA), name path global = traj]
        (C'-\solA) circle [radius = 1];
      \end{scope}

      \path[name path = circ] (B) circle [radius = 1bp];

      \draw[name intersections = {of = circ and traj}, -latex] (B) --
      ($(intersection-1)!1.25cm!(intersection-2)$) coordinate (P3);
      \draw[name intersections = {of = circ and ell2}, -latex, red] (B) --
      ($(intersection-1)!2cm!(intersection-2)$) coordinate (P4);
      \draw[-latex, name path = line3] (P3) -- (P4);
      \draw[name path = line4] (B) -- ($(B)!2.1cm!-90:(F)$) coordinate (P5);

      \path[name path = circ2] (P3) circle [radius = 1bp];
      \path[name intersections = {of = circ2 and line3}, name path = line5]
      (P3) -- ($(intersection-1)!2cm!(P3)$);
      \path[name intersections = {of = line5 and line4, by = P6}];

      \path[name intersections = {of = circ and traj}] (B) --
      ($(intersection-1)!1.5cm!(intersection-2)$) coordinate (P7);

      \path[name intersections = {of = circ and ell2}] (B) --
      ($(intersection-1)!2.5cm!(intersection-2)$) coordinate (P8);

      \draw[-latex] let
        \p0 = (P6),
        \p1 = (P5),
        \p2 = (P4),
        \n1 = {atan2(\x1 - \x0, \y1 - \y0)},
        \n2 = {atan2(\x2 - \x0, \y2 - \y0)-360},
        \n3 = {.75cm}
      in (P6) +(\n1:\n3) arc[radius = \n3, start angle = \n1, end angle = \n2];

          \end{scope}
  \end{tikzpicture}

\end{document}

相关内容