Tikz - 绘制与另一条曲线的切线相切的曲线

Tikz - 绘制与另一条曲线的切线相切的曲线

我想绘制左侧面板(我手动在其中放置了蓝色曲线)。但右侧面板中的曲线不同。如何绘制左侧面板中所示的曲线(无需手动计算蓝色曲线的位置)?

相关问题,如何获得切线坐标系(使用scope),其 x 轴为黑色切线,原点为标记点?

\documentclass[a4paper,12pt]{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{intersections}
\usetikzlibrary{decorations.markings}

\tikzset{
  tangent pos/.style={decoration={markings, mark = at position #1 with {
        \coordinate (tangent point-\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}) at (0pt,0pt);
        \coordinate (tangent unit vector-\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}) at (1,0pt);
        \coordinate (tangent orthogonal unit vector-\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}) at (0pt,1);
      }
    },
    postaction=decorate
  },
  %
  tangent/.style={shift=(tangent point-#1), x=(tangent unit vector-#1), y=(tangent orthogonal unit vector-#1)},
}

\newcommand*{\tpointmark}[2][]{\fill [smooth,fill=black#1] (#2) circle (0.05)}

\begin{document}

\begin{figure} [!htbp]
  \centering
  \begin{tikzpicture} [font=\footnotesize]
    \draw [thick,<->] (0,5) node[above]{$Y$} -- (0,0) node[below left]{$0$} coordinate (axis1) -- (5,0) node[right]{$X$};

    \draw [smooth,red,thick,tangent pos=0.3] (0,4.5) to[out=0, in=90] (3.5,0);
    \draw [smooth,black,tangent=1,tangent pos=0.8] (-1,0) -- coordinate[pos=0.8] (A) (4,0);
    \draw [smooth,blue,thick] (3.85,2.95) to[out=270, in=180] (4.85,1.95);

    \tpointmark{A};
  \end{tikzpicture}
  \qquad
  \begin{tikzpicture} [font=\footnotesize]
    \draw [thick,<->] (0,5) node[above]{$Y$} -- (0,0) node[below left]{$0$} coordinate (axis1) -- (5,0) node[right]{$X$};

    \draw [smooth,red,thick,tangent pos=0.3] (0,4.5) to[out=0, in=90] (3.5,0);
    \draw [smooth,black,tangent=1,tangent pos=0.8] (-1,0) -- coordinate[pos=0.8] (A) (4,0);
    \draw [smooth,blue,thick,tangent=1] (-1,0.5) to[out=-45,in=180] (0,0) to[out=0,in=-135] (1,0.5);

    \tpointmark{A};
  \end{tikzpicture}
\end{figure}

\end{document}

答案1

欢迎!有两个问题:当您在另一个切线坐标系中设置切线坐标系时,您会获得额外的旋转。因此,我在使用原始坐标系的一条线上创建了第二个切线系统。此外,入角和出角是绝对的,因此您需要添加当前帧的旋转角度。

\documentclass[a4paper,12pt]{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{intersections}
\usetikzlibrary{decorations.markings}

\tikzset{
  tangent pos/.style={decoration={markings, mark = at position #1 with {
        \coordinate (tangent point-\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}) at (0pt,0pt);
        \coordinate (tangent unit vector-\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}) at (1,0pt);
        \coordinate (tangent orthogonal unit vector-\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}) at (0pt,1);
      }
    },
    postaction=decorate
  },
  %
  tangent/.style={shift=(tangent point-#1), x=(tangent unit vector-#1), y=(tangent orthogonal unit vector-#1)},
}

\newcommand*{\tpointmark}[2][]{\fill [smooth,fill=black#1] (#2) circle (0.05)}

\begin{document}

\begin{figure} [!htbp]
  \centering
  \begin{tikzpicture} [font=\footnotesize]
    \draw [thick,<->] (0,5) node[above]{$Y$} -- (0,0) node[below left]{$0$} coordinate (axis1) -- (5,0) node[right]{$X$};

    \draw [smooth,red,thick,tangent pos=0.3] (0,4.5) to[out=0, in=90] (3.5,0);
    \draw [smooth,black,tangent=1,tangent pos=0.8] (-1,0) -- coordinate[pos=0.8] (A) (4,0);
    \draw [smooth,blue,thick] (3.85,2.95) to[out=270, in=180] (4.85,1.95);

    \tpointmark{A};
  \end{tikzpicture}
  \qquad
  \begin{tikzpicture} [font=\footnotesize]
    \draw [thick,<->] (0,5) node[above]{$Y$} -- (0,0) node[below left]{$0$} coordinate (axis1) -- (5,0) node[right]{$X$};

    \draw [smooth,red,thick,tangent pos=0.3] (0,4.5) to[out=0, in=90] (3.5,0);
    \draw [black,tangent=1] (-1,0) coordinate (A0) -- coordinate[pos=0.8] (A) 
    (4,0) coordinate (A1);
    \path [tangent pos=0.8] (A0) -- (A1);
    \draw [smooth,blue,thick,tangent=1] 
    let \p1=($(1,0)-(0,0)$),
        \n1={atan2(\y1,\x1)} in 
        (-1,0.5) to[out=-45+\n1,in=180+\n1] 
    (0,0) to[out=0+\n1,in=-135+\n1] (1,0.5);
    \tpointmark{A};
  \end{tikzpicture}
\end{figure}
\end{document}

在此处输入图片描述

您可以通过以下方式避免这种情况:不设置局部框架的单位向量,而是找到带您到达该位置的旋转。对于当前示例,这会使事情变得更容易,但也有缺点,因为如果您现在说transform shape节点文本将被旋转。

\documentclass[a4paper,12pt]{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{intersections}
\usetikzlibrary{decorations.markings}

\tikzset{
  tangent pos/.style={decoration={markings, mark = at position #1 with {
        \coordinate (tangent point-\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}) at (0pt,0pt);
        \coordinate (tangent unit vector-\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}) at (1,0pt);
        \coordinate (tangent orthogonal unit vector-\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}) at (0pt,1);
      }
    },
    postaction=decorate
  },
  %
  tangent/.style={shift=(tangent point-#1),
  insert path={let \p1=($(tangent unit vector-#1)-(tangent point-#1)$),
  \n1={atan2(\y1,\x1)} in [rotate=\n1]}
   %x=(tangent unit vector-#1), y=(tangent orthogonal unit vector-#1)
   },
}

\newcommand*{\tpointmark}[2][]{\fill [smooth,fill=black#1] (#2) circle (0.05)}

\begin{document}

\begin{figure} [!htbp]
  \centering
  \begin{tikzpicture} [font=\footnotesize]
    \draw [thick,<->] (0,5) node[above]{$Y$} -- (0,0) node[below left]{$0$} coordinate (axis1) -- (5,0) node[right]{$X$};

    \draw [smooth,red,thick,tangent pos=0.3] (0,4.5) to[out=0, in=90] (3.5,0);
    \draw [smooth,black,tangent=1,tangent pos=0.8] (-1,0) -- coordinate[pos=0.8] (A) (4,0);
    \draw [smooth,blue,thick] (3.85,2.95) to[out=270, in=180] (4.85,1.95);

    \tpointmark{A};
  \end{tikzpicture}
  \qquad
  \begin{tikzpicture} [font=\footnotesize]
    \draw [thick,<->] (0,5) node[above]{$Y$} -- (0,0) node[below left]{$0$} coordinate (axis1) -- (5,0) node[right]{$X$};

    \draw [smooth,red,thick,tangent pos=0.3] (0,4.5) to[out=0, in=90] (3.5,0);
    \draw [black,tangent=1,tangent pos=0.8] (-1,0)  -- coordinate[pos=0.8] (A) 
    (4,0);
    \draw [smooth,blue,thick,tangent=1]     (-1,0.5) to[out=-45,in=180] 
        (0,0) to[out=0,in=-135] (1,0.5);
    \tpointmark{A};
  \end{tikzpicture}
\end{figure}
\end{document}

在此处输入图片描述

最后,这里根本不需要显式切线坐标系。您只需定义一个图片,它只是一些代码的包装器。如果您使用slopedtransform shape它也会将您带入切线空间。

\documentclass[a4paper,12pt]{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{intersections}
\usetikzlibrary{decorations.markings}

\tikzset{
  tangent pos/.style={decoration={markings, mark = at position #1 with {
        \coordinate (tangent point-\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}) at (0pt,0pt);
        \coordinate (tangent unit vector-\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}) at (1,0pt);
        \coordinate (tangent orthogonal unit vector-\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}) at (0pt,1);
      }
    },
    postaction=decorate
  },
  %
  tangent/.style={shift=(tangent point-#1),
  insert path={let \p1=($(tangent unit vector-#1)-(tangent point-#1)$),
  \n1={atan2(\y1,\x1)} in [rotate=\n1]}
   %x=(tangent unit vector-#1), y=(tangent orthogonal unit vector-#1)
   },
  pics/whatever/.style={code={#1}} 
}

\newcommand*{\tpointmark}[2][]{\fill [smooth,fill=black#1] (#2) circle (0.05)}

\begin{document}

\begin{figure} [!htbp]
  \centering
  \begin{tikzpicture} [font=\footnotesize]
    \draw [thick,<->] (0,5) node[above]{$Y$} -- (0,0) node[below left]{$0$} coordinate (axis1) -- (5,0) node[right]{$X$};

    \draw [smooth,red,thick,tangent pos=0.3] (0,4.5) to[out=0, in=90] (3.5,0);
    \draw [smooth,black,tangent=1,tangent pos=0.8] (-1,0) -- coordinate[pos=0.8] (A) (4,0);
    \draw [smooth,blue,thick] (3.85,2.95) to[out=270, in=180] (4.85,1.95);

    \tpointmark{A};
  \end{tikzpicture}
  \qquad
  \begin{tikzpicture} [font=\footnotesize]
    \draw [thick,<->] (0,5) node[above]{$Y$} -- (0,0) node[below left]{$0$} coordinate (axis1) -- (5,0) node[right]{$X$};

    \draw [smooth,red,thick,tangent pos=0.3] (0,4.5) to[out=0, in=90] (3.5,0);
    \draw [black,tangent=1] (-1,0)  -- coordinate[pos=0.8] (A) 
    (4,0) pic[sloped,pos=0.8,transform shape]{whatever={\draw [smooth,blue,thick]   (-1,0.5) to[out=-45,in=180] 
        (0,0) to[out=0,in=-135] (1,0.5);}};

    \tpointmark{A};
  \end{tikzpicture}
\end{figure}
\end{document}

与以前的结果相同。

答案2

使用tzplot包裹:

在此处输入图片描述

\documentclass[tikz]{standalone}
    
\usepackage{tzplot}

\begin{document}

\begin{tikzpicture}
\tzhelplines(5,5)
\tzaxes(5,5){$X$}{$Y$}
% red curve: PPC
\tzto[red,thick,out=0,in=90]"curve"(0,4.5)(3.5,0)
% tangent line
\settztangentlayer{main}
\tztangentat"tan"{curve}{1.5}[.5:5]
% dots
\tzvXpointat*{curve}{1.5}(P){$P$}[45]
\tzvXpointat*{tan}{4}(Q){$Q$}[45]
% extract angle between points, saved at \tzangleresult
\tzanglemark[draw=none](P)(Q)(Q-|5,0)
% blue curve: IC
\tztos[blue,thick]($(Q)+(-.7,1)$)
      [out=-75,in=\tzangleresult](Q)
      [out=\tzangleresult-180,in=175]($(Q)+(1,-.3)$);
\end{tikzpicture}

\end{document}

答案3

我找到了另一种方法。

\documentclass[a4paper,12pt]{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{intersections}
\usetikzlibrary{decorations.markings}

\tikzset{
  tangent pos/.style={decoration={markings, mark = at position #1 with {
        \coordinate (tangent point-\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}) at (0pt,0pt);
        \coordinate (tangent unit vector-\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}) at (1,0pt);
        \coordinate (tangent orthogonal unit vector-\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}) at (0pt,1);
      }
    },
    postaction=decorate
  },
  %
  tangent/.style={shift=(tangent point-#1), x=(tangent unit vector-#1), y=(tangent orthogonal unit vector-#1)},
}

\newcommand*{\tpointmark}[2][]{\fill [smooth,fill=black#1] (#2) circle (0.05)}

\begin{document}

\begin{figure} [!htbp]
  \centering
  \begin{tikzpicture} [font=\footnotesize]
    \draw [thick,<->] (0,5) node[above]{$y$} -- (0,0) node[below left]{$0$} coordinate (axis1) -- (5,0) node[right]{$x$};

    \draw [smooth,red,thick,tangent pos=0.3] (0,4.5) to[out=0, in=90] coordinate[pos=0.3] (E) (3.5,0);

    \draw [black,tangent=1] (-1,0) coordinate (T1) -- coordinate[pos=0.8] (A) (4,0) coordinate (T2);
    % Below we calculate the angle of the tangent
    \pgfmathanglebetweenpoints{\pgfpointanchor{T1}{center}}{\pgfpointanchor{T2}{center}};
    \begin{scope} [shift={(A)}, rotate around={\pgfmathresult:(A)}]
      % Now we are in the coordinate system whose origin is (A)
      % and slope of the x-axis is the slope of the tangent.
      \draw [smooth,blue,thick] (-1,0.5) to[out=-45,in=180] (0,0) to[out=0,in=-135] (1,0.5);
    \end{scope}

    \tpointmark{E};
    \tpointmark{A};
  \end{tikzpicture}
\end{figure}

\end{document}

答案4

TikZ 绘制切线的通常方式是使用decorations.markings,即将切线作为装饰。

此(普通) Asymptote 方法用于比较。对于 Asymptote,切线/法线运算是内置的,因此它让我在绘制此类图形时从数学上感到很舒服。

给定pathP一个实数- 相对位置,我们可以在该路径上t取一个点,并取处的入切线, 。现在我们可以得到这样的切线段。Ppair P=relpoint(pathP,t);Ppair Pt=dir(pathP,t);P-2Pt--P+4Pt

接下来我们可以Q在切线段上取一个点。从Q我们控制 2 条路径,pathQleftpath Qright,从 Q 开始沿切线方向(无需计算角度、斜率)。这就是图形的简单性!

在此处输入图片描述

unitsize(1cm);
import math;   // for grid
add(grid(5,5,lightgray));
path pathP=(0,4.5) {right}..(3.5,0){down};
real t=.3;
pair P=relpoint(pathP,t);
pair Pt=dir(pathP,t);
draw(pathP,deepcyan);
draw(P-2Pt--P+4Pt,red);
pair Q=P+2.5Pt;
path pathQright=Q .. controls Q+Pt and  Q+(2,.5)+dir(-130) .. Q+(2,.5);
path pathQleft=Q .. controls Q-Pt and  Q+(-1,2)+dir(-70) .. Q+(-1,2);

draw(pathQright^^pathQleft,blue);
dot("$P$",align=NE,P,deepcyan);
dot("$Q$",align=SW,Q,blue);

draw(Label("$x$",EndPoint,align=SE),(0,0)--(5.5,0),Arrow(TeXHead));
draw(Label("$y$",EndPoint,align=W),(0,0)--(0,5.5),Arrow(TeXHead));
shipout(bbox(5mm,invisible));

相关内容