![TikZ/PGF绘制算法](https://linux22.com/image/395241/TikZ%2FPGF%E7%BB%98%E5%88%B6%E7%AE%97%E6%B3%95.png)
我有绘制椭圆的 TikZ 代码。据我所知,这是绘制实际椭圆的代码:
\draw [rotate around={0.:(0.,0.)},line width=0.8pt] (0.,0.) ellipse (5.cm and 4.cm);
有人能告诉我draw
实际上是如何产生线条的吗,即它是否在后台使用插值算法来创建坐标点?
我用过Geogebra生成图形的 TikZ 代码,有时它会通过生成大量单独的坐标来强制线条或物体的形状,这使得它很难放入 LaTeX 文档中。
然而,这对我来说意味着,仅使用上面这样的一行代码来实际绘制形状是一种插值,即根据椭圆公式绘制最小基点集,然后插入其余点以填充它们之间。我读到这是典型的,因为使用椭圆公式来产生全部的点数将非常耗费资源和时间。有人知道幕后发生了什么吗?
答案1
正如 JouleV 指出的那样,椭圆由四条贝塞尔曲线绘制而成。如果您不想在代码中查找这些内容,您可以随时使用来show path construction
查看路径的构造方式。
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{decorations.pathreplacing}
\begin{document}
\begin{tikzpicture}[decoration={show path construction, % see p. 634 of the pgfmanual
moveto code={
\fill [red] (\tikzinputsegmentfirst) circle (2pt)
node [fill=none, below] {moveto};},
lineto code={
\draw [blue,->] (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast)
node [above] {lineto};
},
curveto code={
\draw [green!75!black,->] (\tikzinputsegmentfirst) .. controls
(\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
..(\tikzinputsegmentlast) node [above] {curveto};
},
closepath code={
\draw [orange,->] (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast)
node [above] {closepath};}
}]
\draw [rotate around={0.:(0.,0.)},line width=0.8pt,postaction=decorate] (0.,0.) ellipse (5.cm and 4.cm);
\end{tikzpicture}
\end{document}
对于圆圈来说也是如此,这就是为什么旋转圆圈可以修改其边界框。
答案2
pgfcorepathconstruct.code.tex
,第 892 至 1010 行:
% Append an ellipse to the current path.
%
% #1 = center
% #2 = first axis
% #3 = second axis
%
% Example:
%
% % Add a circle of radius 3cm around the origin
% \pgfpathellipse{\pgforigin}{\pgfxy(2,0)}{\pgfxy(0,1)}
%
% % Draw a non-filled circle of radius 1cm around the point (1,1)
% \pgfpathellipse{\pgfxy(1,1)}{\pgfxy(1,1)}{\pgfxy(-2,2)}
% \pgfstroke
\def\pgfpathellipse#1#2#3{%
\pgfpointtransformed{#1}% store center in xc/yc
\pgf@xc=\pgf@x%
\pgf@yc=\pgf@y%
\pgfpointtransformed{#2}%
\pgf@xa=\pgf@x% store first axis in xa/ya
\pgf@ya=\pgf@y%
\advance\pgf@xa by-\pgf@pt@x%
\advance\pgf@ya by-\pgf@pt@y%
\pgfpointtransformed{#3}%
\pgf@xb=\pgf@x% store second axis in xb/yb
\pgf@yb=\pgf@y%
\advance\pgf@xb by-\pgf@pt@x%
\advance\pgf@yb by-\pgf@pt@y%
{%
\advance\pgf@xa by\pgf@xc%
\advance\pgf@ya by\pgf@yc%
\pgf@nlt@moveto{\pgf@xa}{\pgf@ya}%
}%
\pgf@x=0.55228475\pgf@xb% first arc
\pgf@y=0.55228475\pgf@yb%
\advance\pgf@x by\pgf@xa%
\advance\pgf@y by\pgf@ya%
\advance\pgf@x by\pgf@xc%
\advance\pgf@y by\pgf@yc%
\edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}%
\pgf@x=0.55228475\pgf@xa%
\pgf@y=0.55228475\pgf@ya%
\advance\pgf@x by\pgf@xb%
\advance\pgf@y by\pgf@yb%
{%
\advance\pgf@x by\pgf@xc%
\advance\pgf@y by\pgf@yc%
\advance\pgf@xb by\pgf@xc%
\advance\pgf@yb by\pgf@yc%
\pgf@temp%
\pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xb}{\pgf@yb}%
}%
\pgf@xa=-\pgf@xa% flip first axis
\pgf@ya=-\pgf@ya%
\pgf@x=0.55228475\pgf@xa% second arc
\pgf@y=0.55228475\pgf@ya%
\advance\pgf@x by\pgf@xb%
\advance\pgf@y by\pgf@yb%
\advance\pgf@x by\pgf@xc%
\advance\pgf@y by\pgf@yc%
\edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}%
\pgf@x=0.55228475\pgf@xb%
\pgf@y=0.55228475\pgf@yb%
\advance\pgf@x by\pgf@xa%
\advance\pgf@y by\pgf@ya%
{%
\advance\pgf@x by\pgf@xc%
\advance\pgf@y by\pgf@yc%
\advance\pgf@xa by\pgf@xc%
\advance\pgf@ya by\pgf@yc%
\pgf@temp%
\pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xa}{\pgf@ya}%
}%
\pgf@xb=-\pgf@xb% flip second axis
\pgf@yb=-\pgf@yb%
\pgf@x=0.55228475\pgf@xb% third arc
\pgf@y=0.55228475\pgf@yb%
\advance\pgf@x by\pgf@xa%
\advance\pgf@y by\pgf@ya%
\advance\pgf@x by\pgf@xc%
\advance\pgf@y by\pgf@yc%
\edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}%
\pgf@x=0.55228475\pgf@xa%
\pgf@y=0.55228475\pgf@ya%
\advance\pgf@x by\pgf@xb%
\advance\pgf@y by\pgf@yb%
{%
\advance\pgf@x by\pgf@xc%
\advance\pgf@y by\pgf@yc%
\advance\pgf@xb by\pgf@xc%
\advance\pgf@yb by\pgf@yc%
\pgf@temp%
\pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xb}{\pgf@yb}%
}%
\pgf@xa=-\pgf@xa% flip first axis once more
\pgf@ya=-\pgf@ya%
\pgf@x=0.55228475\pgf@xa% fourth arc
\pgf@y=0.55228475\pgf@ya%
\advance\pgf@x by\pgf@xb%
\advance\pgf@y by\pgf@yb%
\advance\pgf@x by\pgf@xc%
\advance\pgf@y by\pgf@yc%
\edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}%
\pgf@x=0.55228475\pgf@xb%
\pgf@y=0.55228475\pgf@yb%
\advance\pgf@x by\pgf@xa%
\advance\pgf@y by\pgf@ya%
{%
\advance\pgf@x by\pgf@xc%
\advance\pgf@y by\pgf@yc%
\advance\pgf@xa by\pgf@xc%
\advance\pgf@ya by\pgf@yc%
\pgf@temp%
\pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xa}{\pgf@ya}%
}%
\pgf@nlt@closepath%
\pgf@nlt@moveto{\pgf@xc}{\pgf@yc}%
}
好吧,只要阅读那里的评论,您就会知道是ellipse
由四条不同的曲线绘制的(每条曲线都用绘制\pgf@nlt@curveto
)。
请注意, 也会发生同样的情况circle
。