我想绘制下面的图像 - 两条曲线之间的渐变,这两条曲线不一定是函数,并且可能可以通过某些点之间的贝塞尔曲线更好地描述。
我见过一些例子,但它们都涉及函数或圆弧或平行曲线。
我已经详细绘制了曲线:
\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{svg.path}
\usetikzlibrary{intersections}
\begin{document}
\begin{tikzpicture}
\begin{scope}[yscale=-1,xscale=1]
\draw [name path=L, green] svg {M201.1,673.2c1.4-39.8,2-52.2,18.2-70.8c11.7-13.5,18.3-24.3-7.7-49.4
c-39.3-38-43.2-59.2,1-90.2c18.1-12.7,67.1-20.2,25.4-36.6c-18.2-7.2-23.5-9.7-26.9-39.2c-3-26.7-17.7-28.2-37.7-35
c-20-6.9-87.7-28.8-50.2-78.2c23.5-31,58.6-73.9,83.1-118.2c13.3-24,22.4-56.5,38.6-85.9};
\draw [name path=R, blue] svg {M295,69.4c-5.1,25.7-13.3,57.3-19.2,76.5
c-15,48.3-21.9,52.2-36.7,86.5c-21.5,49.9-47.2,77.8-1.1,90.5c46.7,12.8,49.7,16,48.9,40.6c-0.6,18.4-3.9,35.1,10.3,34.3
c15.7-0.9,40.5,6,71.5,36.8c8.2,8.1,25,18.7,25,18.7s-159.2,8.6-116.4,73.2c29.6,44.7,31.9,44.4,19.9,66.7
c-15.1,28.3-28.8,48.8-23,80.6};
\end{scope}
\end{tikzpicture}
\end{document}
得出的结果是:
这是最简单的部分。我仍在寻找将一条曲线转换为另一条曲线并在此过程中改变颜色的方法。
答案1
如果您查看原始图形,您可能会发现阴影区域仅从中间到左侧,从中间到右侧几乎完全是黑色。因此,将图形一分为二,并根据 Peter Grill 的建议、OP 定义的 SVG 路径和其他人的建议,这里有一个将整个曲线向右移动的解决方案:
\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{svg.path}
\usepackage{spath} % Package for manipulating paths by Andrew Stacey
% The curve that will be repeated to the left at a lower-tone.
\newcommand{\MiddleC}{%
[xshift=25] svg {M201.1,673.2c1.4-39.8,2-52.2,18.2-70.8c11.7-13.5,18.3-24.3-7.7-49.4
c-39.3-38-43.2-59.2,1-90.2c18.1-12.7,67.1-20.2,25.4-36.6c-18.2-7.2-23.5-9.7-26.9-39.2c-3-26.7-17.7-28.2-37.7-35
c-20-6.9-87.7-28.8-50.2-78.2c23.5-31,58.6-73.9,83.1-118.2c13.3-24,22.4-56.5,38.6-85.9};
}
% The repetition of this curve, by Peter Grill - answer 1.
\newcommand{\MyScope}[1][]{%
\begin{scope}[cap=round, #1]
\path[draw=black] \MiddleC;
\end{scope}
}
\newlength{\shift}
\begin{document}
\begin{tikzpicture}[transform canvas={yscale=-1}] %SVG curves were upside down.
\path [save path=\Left] svg {M201.1,673.2c1.4-39.8,2-52.2,18.2-70.8c11.7-13.5,18.3-24.3-7.7-49.4
c-39.3-38-43.2-59.2,1-90.2c18.1-12.7,67.1-20.2,25.4-36.6c-18.2-7.2-23.5-9.7-26.9-39.2c-3-26.7-17.7-28.2-37.7-35
c-20-6.9-87.7-28.8-50.2-78.2c23.5-31,58.6-73.9,83.1-118.2c13.3-24,22.4-56.5,38.6-85.9};
\path [save path=\Middle, xshift=25] svg {M201.1,673.2c1.4-39.8,2-52.2,18.2-70.8c11.7-13.5,18.3-24.3-7.7-49.4
c-39.3-38-43.2-59.2,1-90.2c18.1-12.7,67.1-20.2,25.4-36.6c-18.2-7.2-23.5-9.7-26.9-39.2c-3-26.7-17.7-28.2-37.7-35
c-20-6.9-87.7-28.8-50.2-78.2c23.5-31,58.6-73.9,83.1-118.2c13.3-24,22.4-56.5,38.6-85.9};
\path [save path=\Right] svg {M295,69.4c-5.1,25.7-13.3,57.3-19.2,76.5
c-15,48.3-21.9,52.2-36.7,86.5c-21.5,49.9-47.2,77.8-1.1,90.5c46.7,12.8,49.7,16,48.9,40.6c-0.6,18.4-3.9,35.1,10.3,34.3
c15.7-0.9,40.5,6,71.5,36.8c8.2,8.1,25,18.7,25,18.7s-159.2,8.6-116.4,73.2c29.6,44.7,31.9,44.4,19.9,66.7
c-15.1,28.3-28.8,48.8-23,80.6};
% Concatenating the 4 paths so we can get the black part:
\pgfoonew \patha=new spath(\Middle)
\pgfoonew \pathb=new spath(\Right)
\patha.concatenate with lineto(,\pathb)
\patha.close()
% Drawing and filling the black part:
\patha.use path with tikz(line width=3pt,draw=black,fill=black)
% Repeating the path for the shaded part:
\foreach \x in {1,...,200} {
\pgfmathsetlength{\shift}{\x/2 pt}%
\pgfmathsetmacro{\opacity}{1-\x/100}%
\MyScope[xshift=-\shift, line width=0.5pt, draw opacity=\opacity]
};
% The eye of the bird:
\filldraw[left color=white, right color=white, draw=white] (11.9,15.1) circle [radius=7pt];
\end{tikzpicture}
\end{document}
得出的结果是:
观察发现,在两条曲线之间应用渐变阴影通常需要从一条曲线的每个点到另一条曲线上的一个点的路径,如果其中一条曲线有自相交或水平线与曲线在两个或多个点相交,这可能会非常麻烦。
在当前的情况下,水平线仅在一个点与曲线相交,这使得工作变得更容易一些。
所提出的解决方案是仅使用一种颜色的“缓冲”区域,这将允许人们处理更复杂的情况,直到曲线变得更直,然后将其滑动到另一个。
答案2
非平行路径:
对两个非平行路径之间的区域进行着色的一种方法是在水平路径上从一端到另一端绘制点,并改变这两个点的不透明度:
随着您增加数量\NumberOfVerticalPositions
和\NumberOfHorizontalPoints
获得积分:
笔记:
- 我不熟悉坐标,
svg.path
因此这需要根据您的具体情况进行调整。
平行路径:
不确定是否有内置方法tikz
,但一种方法是自己动手:重新绘制路径并稍微移动并调整不透明度。 您也可以调整线宽,但下面的 MWE 仅调整每条路径的不透明度:
笔记:
- 对于复杂的路径,这可能需要一些修改。
代码:非平行路径
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,intersections}
%\def\DebugEnabled{}% Make sure that the \YMin and \YMax are adequate.
\newcommand*{\NumberOfVerticalPositions}{200}%
\newcommand*{\NumberOfHorizontalPoints}{100}%
\newcommand*{\CircleSize}{0.75pt}% The smaller this is, the larger number of points that are required
\newcommand*{\YMin}{-3.75}% \YMin and \YMax must be chosen such that there is an intersection
\newcommand*{\YMax}{3.75}% of a horizontal line and the two curves.
\newcommand*{\XMin}{-3}% \XMin and \XMax should be overestimates on the min and max values of x
\newcommand*{\XMax}{11}% for which the horizontal line and the two curves intersect.
\begin{document}
\begin{tikzpicture}
\begin{scope}[domain=-3:3]% Two non-parallel paths.
%% Drawing the right one helps to make it smoother
\draw [color=gray, name path global=right curve, line width=2*\CircleSize]
plot (\x*\x,1.25*\x);
\ifdefined\DebugEnabled
\draw
\else
\path
\fi
[color=gray, name path global=left curve, xshift=-80]
plot (\x*\x,1.25*\x);
\end{scope}
\ifdefined\DebugEnabled
%% Make sure that we are covering the entire y range:
%% Use this to determine \YMin and \YMax
\draw [ultra thick, blue] (\XMin,\YMax) -- (\XMax,\YMax);
\draw [ultra thick, red] (\XMin,\YMin) -- (\XMax,\YMin);
\else
\pgfmathsetmacro{\DelatY}{(\YMax-\YMin)/(\NumberOfVerticalPositions-10)}%
%\foreach \y in {\YMin, -2.75, ..., \YMax} {
\foreach \y in {1, ..., \NumberOfVerticalPositions} {
\pgfmathsetmacro{\YCoordinate}{\YMin+\DelatY*(\y-1)}%
%% Create a horizontal path so we can determine the left and right coordinates
\path [ultra thick, gray, name path=horizontal line]
(\XMin,\YCoordinate) -- (\XMax,\YCoordinate);
%% The left and right endpoints are the intersection of the "horizontal line"
%% and the two curves: "left curve" and "right curve"
\path [name intersections={of=horizontal line and left curve, by={left intersection}}]
(left intersection) circle (\CircleSize);
\path [name intersections={of=horizontal line and right curve, by={right intersection}}]
(right intersection) circle (\CircleSize);
\foreach \x in {1, ..., \NumberOfHorizontalPoints} {
\pgfmathsetmacro{\PercentOffset}{\x/\NumberOfHorizontalPoints}%
\fill [black, opacity=\PercentOffset]
($(left intersection)!\PercentOffset!(right intersection)$)
circle (\CircleSize) ;
}
}
\fi
\end{tikzpicture}%
\end{document}
代码:平行路径
\documentclass{article}
\usepackage{tikz}
\newcommand{\MyPath}{%
(0.2,2) .. controls
(0.2,2) and (0.7,3) .. (2,4)
}%
\newcommand{\MyScope}[1][]{%
\begin{scope}[cap=round, #1]
\path[draw=black] \MyPath;
\end{scope}
}
\newlength{\shift}
\begin{document}
\begin{tikzpicture}
\foreach \x in {1,...,50} {
\pgfmathsetlength{\shift}{\x/2 pt}%
\pgfmathsetmacro{\opacity}{1-\x/25}%
\MyScope[yshift=-\shift, line width=0.5pt, draw opacity=\opacity]
}
\end{tikzpicture}%
\end{document}
答案3
本质上,有一种方法可以获得三次曲线之间的梯度。但这种方法是 PDF 的一个非常棘手的功能,有时 PDF 阅读器不会给出任何提示。
\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.14}
\usepgfplotslibrary{patchplots}
\usetikzlibrary{svg.path}
\begin{document}
\begin{tikzpicture}[yscale=-1]
\begin{axis}[]
\addplot[colormap/blackwhite,patch,patch type=coons,shader=interp,point meta=explicit]
table[meta=z]{
x y z
201.1 673.2 10
202.5 633.4 10
203.1 621 10
219.3 602.4 10
219.3 602.4 10
297.2 593.2 9
297.2 593.2 0
282.1 621.5 0
268.4 642 0
274.2 673.8 0
274.2 673.8 9
201.1 673.2 10
%
219.3 602.4 10
231 588.9 10
237.6 578.1 10
211.6 553 10
211.6 553 10
277.3 526.5 9
277.3 526.5 0
306.9 571.2 0
309.2 570.9 0
297.2 593.2 0
297.2 593.2 9
219.3 602.4 10
%
211.6 553 10
172.3 515 10
168.4 493.8 10
212.6 462.8 10
212.6 462.8 10
393.7 453.3 9
393.7 453.3 0
393.7 453.3 0
234.5 461.9 0
277.3 526.5 0
277.3 526.5 9
211.6 553 10
%
212.6 462.8 10
230.7 450.1 10
279.7 442.6 10
238 426.2 10
238 426.2 10
368.7 434.6 9
368.7 434.6 0
376.9 442.7 0
393.7 453.3 0
393.7 453.3 0
393.7 453.3 9
212.6 462.8 10
%
238 426.2 10
219.8 419 10
214.5 416.5 10
211.1 387 10
211.1 387 10
297.2 397.8 9
297.2 397.8 0
312.9 396.9 0
337.7 403.8 0
368.7 434.6 0
368.7 434.6 9
238 426.2 10
%
211.1 387 10
208.1 360.3 10
193.4 358.8 10
173.4 352 10
173.4 352 10
286.9 363.5 9
286.9 363.5 0
286.3 381.9 0
283 398.6 0
297.2 397.8 0
297.2 397.8 9
211.1 387 10
%
173.4 352 10
153.4 345.1 10
85.7 323.2 10
123.2 273.8 10
123.2 273.8 10
238 322.9 9
238 322.9 0
284.7 335.7 0
287.7 338.9 0
286.9 363.5 0
286.9 363.5 9
173.4 352 10
%
123.2 273.8 10
146.7 242.8 10
181.8 199.9 10
206.3 155.6 10
206.3 155.6 10
239.1 232.4 9
239.1 232.4 0
217.6 282.3 0
191.9 310.2 0
238 322.9 0
238 322.9 9
123.2 273.8 10
}
;
\end{axis}
\end{tikzpicture}