在 TikZ 中,可以绘制具有 2 个控制点 p0、p1、p2 和 p3 的 3 度贝塞尔曲线,如下所示:
\draw(p0)..controls (p1) and (p2)..(p3);
我想知道是否有办法绘制一条有 5 个点的贝塞尔曲线,其中 3 个点作为控制点。这样看起来就像:
\draw(p0)..controls (p1) and (p2) and (p3)..(p4);
看起来好像不可用。
答案1
TikZ/PGF 仅具有三次贝塞尔曲线功能,这是其生成的输出格式的一个方面:它们仅支持三次贝塞尔曲线。
- 后记见第 564 页(内部编号,共 578 页)PostScript® 语言参考,第三版,可从http://partners.adobe.com/public/developer/ps/index_specs.html。
- 对于 PDF,您可以在转换为 ISO 之前检查 Adobe 的版本(Adobe 的版本是免费的)Adobe PDF 参考,第六版可从http://www.adobe.com/devnet/pdf.html相关信息从第226页开始。
- 对于 SVG,请参阅http://www.w3.org/TR/SVG11/paths.html#PathDataCurveCommands
因此,要生成任何更高阶的曲线,您必须生成一个近似值(实际上,TikZ/PGF 通过三次贝塞尔曲线近似弧线,因为 PDF 没有原生弧线命令(Postscript 有))。有一些方法可用于实现一个,例如使用命令plot
,但由于它是一种近似值而不是一个常见特征,据我所知,没有现成的实现。如果您找到了一种通过三次贝塞尔曲线近似更高阶曲线的算法,我想不出有什么理由不直接通过某种to path
魔法来实现它。
答案2
以下是创建具有三个控制点的贝塞尔曲线的代码。如果您需要更多或更少的点来绘制曲线,只需修改{0.05,0.1,...,1}
“foreach”行上的参数。使用提供的值,曲线将用 20 个点绘制。P0 和 P4 是端点,而 p1、p2 和 p3 是控制点。
\newcommand {\bezierq}[5]{
%\bezierq{p0}{p1}{p2}{p3}{p4};
\newdimen\pxa
\newdimen\pya
\newdimen\pxb
\newdimen\pyb
\newdimen\pxc
\newdimen\pyc
\newdimen\pxd
\newdimen\pyd
\newdimen\pxe
\newdimen\pye
\pgfextractx{\pxa}{\pgfpointanchor{#1}{center}}
\pgfextracty{\pya}{\pgfpointanchor{#1}{center}}
\pgfextractx{\pxb}{\pgfpointanchor{#2}{center}}
\pgfextracty{\pyb}{\pgfpointanchor{#2}{center}}
\pgfextractx{\pxc}{\pgfpointanchor{#3}{center}}
\pgfextracty{\pyc}{\pgfpointanchor{#3}{center}}
\pgfextractx{\pxd}{\pgfpointanchor{#4}{center}}
\pgfextracty{\pyd}{\pgfpointanchor{#4}{center}}
\pgfextractx{\pxe}{\pgfpointanchor{#5}{center}}
\pgfextracty{\pye}{\pgfpointanchor{#5}{center}}
%\def\pxi{4}
%\def\pyi{4}
\foreach \t in {0.05,0.1,...,1}{
\pgfmathsetmacro{\pxf}{\pxa*(1-\t)^4 + \pxb*4*\t*(1-\t)^3 + \pxc*6*\t^2*(1-\t)^2 + \pxd*4*(1-\t)*\t^3 + \pxe*\t^4}
\pgfmathsetmacro{\pyf}{\pya*(1-\t)^4 + \pyb*4*\t*(1-\t)^3 + \pyc*6*\t^2*(1-\t)^2 + \pyd*4*(1-\t)*\t^3 + \pye*\t^4}
\pgfmathsetmacro{\q}{\t-0.05}
\pgfmathsetmacro{\pxi}{\pxa*(1-\q)^4 + \pxb*4*\q*(1-\q)^3 + \pxc*6*\q^2*(1-\q)^2 + \pxd*4*(1-\q)*\q^3 + \pxe*\q^4}
\pgfmathsetmacro{\pyi}{\pya*(1-\q)^4 + \pyb*4*\q*(1-\q)^3 + \pyc*6*\q^2*(1-\q)^2 + \pyd*4*(1-\q)*\q^3 + \pye*\q^4}
\draw (\pxi pt,\pyi pt)--(\pxf pt,\pyf pt);
}