我想绘制左侧面板(我手动在其中放置了蓝色曲线)。但右侧面板中的曲线不同。如何绘制左侧面板中所示的曲线(无需手动计算蓝色曲线的位置)?
相关问题,如何获得切线坐标系(使用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}
最后,这里根本不需要显式切线坐标系。您只需定义一个图片,它只是一些代码的包装器。如果您使用sloped
,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)
},
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
取一个点,并取处的入切线, 。现在我们可以得到这样的切线段。P
pair P=relpoint(pathP,t);
P
pair Pt=dir(pathP,t);
P-2Pt--P+4Pt
接下来我们可以Q
在切线段上取一个点。从Q
我们控制 2 条路径,pathQleft
和path 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));