我想知道如何$ \epsilon $
在“tikz”中绘制具有平滑边界的集合的邻域。
\documentclass[tikz, border=5mm]{standalone}
\usepackage{tikz}
\usepackage{amsmath}
\begin{document}
\begin{tikzpicture}[>=latex]
\draw plot [smooth cycle, tension=0.6] coordinates {(4.4,0.4) (5,0.2) (5.8,0.6) (6.5773,0.5421)(6.4905,1.1074) (5.9752,1.2828) (5.4,1.4) (4.6,1) };
\end{tikzpicture}
\end{document}
答案1
首先要意识到的是,这是不可能的。PDF,以及 TikZ,只能绘制三次贝塞尔线,而将三次贝塞尔以相同的距离放大到四周会产生不再是三次贝塞尔的东西。
因此,任何解决方案都或多或少会有点儿像黑客手段。
话虽如此,这里有一个解决方案,它确实会产生一条与原始曲线有一定距离的路径。它利用了这样一个事实:当绘制一条线时,其厚度完全遵循您试图强制的约束:绘制线时,在曲线上的任何一点,与曲线正交测量的线的宽度就是给定的厚度。所以如果有一种方法可以在绘制曲线时只绘制粗线的外边缘……
这就是它的作用。为了得到边缘,我们画了两次线,第二次是白色的,比第一次要细一点(因为你想要虚线,我决定不使用,double
因为在查看文档时它会导致伪影)。为了只得到外边缘,我们根据原始曲线进行裁剪。
奇怪的虚线效果是因为虚线沿着原始曲线具有正确的宽度,但随后却按线的厚度按比例缩放(取出白色覆盖即可显示那里发生的情况)。
\documentclass[tikz, border=5mm]{standalone}
%\url{http://tex.stackexchange.com/q/335826/86}
\usepackage{tikz}
\usepackage{amsmath}
\begin{document}
\begin{tikzpicture}[>=latex]
\begin{scope}[even odd rule]
\clip (3,-1) rectangle (8,3) plot [smooth cycle, tension=0.6] coordinates {(4.4,0.4) (5,0.2) (5.8,0.6) (6.5773,0.5421)(6.4905,1.1074) (5.9752,1.2828) (5.4,1.4) (4.6,1) };
\draw[line width=1cm,dashed] plot [smooth cycle, tension=0.6] coordinates {(4.4,0.4) (5,0.2) (5.8,0.6) (6.5773,0.5421)(6.4905,1.1074) (5.9752,1.2828) (5.4,1.4) (4.6,1) };
\draw[line width=.9cm,white] plot [smooth cycle, tension=0.6] coordinates {(4.4,0.4) (5,0.2) (5.8,0.6) (6.5773,0.5421)(6.4905,1.1074) (5.9752,1.2828) (5.4,1.4) (4.6,1) };
\end{scope}
\draw[line width=.5mm] plot [smooth cycle, tension=0.6] coordinates {(4.4,0.4) (5,0.2) (5.8,0.6) (6.5773,0.5421)(6.4905,1.1074) (5.9752,1.2828) (5.4,1.4) (4.6,1) };
\end{tikzpicture}
\end{document}
只要记住:
如果您家附近有奇怪的事情发生,
您会打电话给谁?
TeX-busters!
答案2
如果集合的边界逆时针参数化为 (x(t),y(t)),则其 epsilon 邻域的边界参数化为: 现在假设我们仅给出曲线上的一个有限集,比如说 N 个点 (x(t), y(t)),因此 t 假设模 N 的整数值。然后我们可以用 (x(t+1)-x(t-1))/2 来近似导数 x'(t),对于 y'(t) 也类似。
付诸实践:
\documentclass[tikz, border=5mm]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
%\draw[help lines,line width=.6pt,step=1] (4,0) grid (7,2);
%\draw[help lines,line width=.3pt,step=.1] (4,0) grid (7,2);
\draw plot [smooth cycle, tension=0.6] coordinates
{(4.4,0.4)(4.6,0.25)(5,0.2)(5.4,0.4)(5.8,0.6)(6.3,0.55)(6.55,0.55)
(6.6,0.8)(6.5,1.1)(6.35,1.2)(6,1.3)(5.8,1.35)(5.4,1.4)(5,1.25)
(4.6,1)(4.45,0.8)};
\draw[dashed] plot [smooth cycle, tension=0.6] coordinates
{(4.3,0.37)(4.56,0.14)(5.03,0.06)(5.47,0.26)(5.83,0.44)(6.29,0.42)
(6.59,0.5)(6.7,0.81)(6.57,1.14)(6.39,1.29)(6.03,1.4)(5.82,1.46)
(5.38,1.54)(4.93,1.39)(4.52,1.1)(4.34,0.84)};
\end{tikzpicture}
\end{document}
这里我使用的点数是原来给出的两倍。结果并不完美(特别是在曲率较大的区域),但增加点数当然可以提高质量。
我用的是Google 电子表格。我确信有一种方法可以告诉 TikZ 进行计算,但我太懒了,没有找到它。如果有人想附加我的答案并自动执行此部分,请随意这样做。
答案3
使用 Asymptote,我沿着曲线(比如 G)取点,然后取在法向量方向上距离 $\epsilon$ 的点,最后平滑地连接它们。这样我们就可以以所需的精度绘制 $\varepsilon$ 邻域的边界。
对于通常情况下较小的 $\epsilon$ 且 G 具有相当简单的形状的情况,这已经足够了。对于 G 的更复杂形状,$\epsilon$ 边界曲线可能会自相交,需要进行一些改进。
unitsize(1cm);
real e=.1; // size of $\epsilon$
pair[] epoints;
pair[] points={(4.4,0.4),(4.6,0.25),(5,0.2),(5.4,0.4),(5.8,0.6),(6.3,0.55),(6.55,0.55),
(6.6,0.8),(6.5,1.1),(6.35,1.2),(6,1.3),(5.8,1.35),(5.4,1.4),(5,1.25),
(4.6,1),(4.45,0.8)};
guide c=operator..(...points)..cycle;
for (real t=0; t<length(c); t=t+.1){
pair pt=point(c,t);
pair qt=pt+scale(e)*rotate(-90)*dir(c,t);
epoints.push(qt);
//draw(circle(pt,e),cyan+opacity(.3)); // to see rolling circles along the curve
}
draw(c);
draw(operator..(...epoints)..cycle,red);
沿曲线滚动圆圈:
更新在一些情况下,我们需要一个(平面)域的 e 邻域,该域D
由曲线界定c
,并且不小的值e
,即 的明可夫斯基D
和 和e
半径圆。对于凸多边形c
,上述方法很有效。
unitsize(1cm);
real e=.5; // size of $\epsilon$
// for convex polygon >> OK!
//pair[] points={(0,0), (5,0), (3,4), (1,3.5)};
// concave polygon >> fill is OK, draw is not OK
pair[] points={(0,0), (5,0), (2,1), (1,3.5)};
path c=operator--(...points)--cycle;
pair[] epoints; // points on $\epsilon$-boundary of c
real tstep=.01;
for (real t=0; t<length(c); t=t+tstep){
pair pt=point(c,t);
pair qt=pt+scale(e)*rotate(-90)*dir(c,t);
epoints.push(qt);
//draw(circle(pt,e),cyan+opacity(.5)); // to see rolling circles along the curve
}
fill(operator..(...epoints)..cycle,yellow+opacity(.5));
draw(operator..(...epoints)..cycle,red);
draw(c);
但是,在凹多边形的情况下,填充 e 边界内是可以的,但由于自相交,绘制并不像预期的那样。目前我不知道如何克服这个问题。
有了operator--
,事情就糟糕了^^
fill(operator--(...epoints)--cycle,yellow+opacity(.5));
draw(operator--(...epoints)--cycle,red);
答案4
这是一个具有ellipse
形状的简单解决方案,但也许您正在寻找特定的设置形状。
\documentclass[tikz, border=5mm]{standalone}
\usepackage{tikz}
\usepackage{amsmath}
\begin{document}
\begin{tikzpicture}[>=latex]
\draw[dashed] (0,0) ellipse (4cm and 2cm);
\draw (0,0) ellipse (3cm and 1.5cm);
\draw[<->] (0,1.5) -- (0,2) node[right,midway] {$\epsilon$};
\end{tikzpicture}
\end{document}