概述

概述

概述

希望模拟以下正弦波,其填充和轮廓厚度均有随机变化:

波浪线

波形由两部分组成:厚度可变的填充和厚度可变的轮廓。MetaPostfunction函数允许通过函数调用创建路径,例如sin。可以使用以下方法创建初始曲线:

path wave;
wave := curved function( 1, "sin(x)", "x", 1, 10, 1 ) xyscaled( 1cm, 1cm );

这产生了一个相当接近的结果:

示例结果

问题

我曾尝试制作一支粗细不一的笔:

  pen variably_thick;
  variably_thick := pencircle yscaled uniformdeviate( 1mm ) rotated 10;

然而,这设置了初始笔的粗细——在绘制路径时没有回调来增加或减少笔的粗细。

代码

一个工作示例:

\setupcolors[state=start]

\definecolor[BaseColour][h=66CEF1]

% Randomize the seed without having to delete the tuc file.
\ctxlua{math.randomseed( os.time() )}

% Draws three waves, somewhat evenly spaced, with two inflection points
% per line.
\startuseMPgraphic{page:ThemeElementWave}
  color base_colour;
  base_colour := \MPcolor{BaseColour};

  % The wavy shape used for creating the wave and its border.
  path wave;

  % The wave "path"
  path underwave;

  % The wave "fill"
  path overwave;

  % Create the base path
  wave := curved function( 1, "sin(x)", "x", 1, 10, 1 ) xyscaled( 1cm, 1cm );

  % Draw the "path" for the wave (the outside edges)
  underwave := wave rotated 90 xscaled 5 yscaled .45;
  draw underwave withpen pencircle scaled 1.25cm withcolor (.7[base_colour,white]);

  % "Fill" the wave.
  overwave := wave rotated 90 xscaled 5 yscaled .5;
  draw overwave withpen pencircle scaled 1cm withcolor base_colour;
\stopuseMPgraphic

\defineoverlay[page:ThemeElementWave][\uniqueMPgraphic{page:ThemeElementWave}]

\starttext
  \setupbackgrounds[page][background={page:ThemeElementWave}]
  \startchapter
  \input knuth
  \stopchapter
\stoptext

问题

如何在 MetaPost 中创建一条可产生粗细不一的线条的曲线?

想法

来自MetaPost 示例

  path p;
  p =
  (0,u)
  for i=.1 step .1 until 10:
    hide( pair A; A = (i*u, (sind (i*180/3.14))/i *u);
          draw A withpen pencircle scaled 2pt )
    .. A
  endfor;
  draw p;

应该可以使用上面的代码(即循环正弦波)来绘制曲线,同时在整个循环过程中改变笔的粗细,但我希望有更清晰的解决方案。

有关的

答案1

虽然这不能回答粗细曲线的问题,但模拟所需结果的另一种方法是将曲线视为两个偏移正弦波,两端连接:

\startuseMPgraphic{page:ThemeElementWave}
  color base_colour;
  base_colour := \MPcolor{BaseColour};

  deviation_dark := uniformdeviate( .025 );
  def dark_colour = deviation_dark [base_colour, black] enddef;

  wave_height := 1.5mm;

  path top_wave;
  top_wave := (0, 0);

  wave_resolution := 20;

  for x = 0 step (1 / wave_resolution) until 2:
    y := sin( x * pi );
    top_wave := top_wave .. (x, y);
  endfor;

  % Duplicate the top wave, but move it up a random amount.
  path bottom_wave;
  bottom_wave := top_wave shifted( 0, wave_height );

  % Offset the waves.
  top_wave := top_wave xyscaled (5.5cm, 5mm);
  bottom_wave := bottom_wave xyscaled (6.5cm, 4.5mm);

  % Create a path for connecting the waves.
  path wave_right_side;
  wave_right_side :=
    (point length(top_wave) of top_wave) --
    (point length(bottom_wave) of bottom_wave);

  % Connect the waves.
  path wave;
  wave := top_wave & wave_right_side & reverse bottom_wave -- cycle;

  % Stretch the wave to extend beyond the page boundaries.
  wave := wave xscaled( 2.5 );

  draw wave withpen pencircle scaled 3mm withcolor .7[base_colour,white];
  fill wave withcolor dark_colour;
\stopuseMPgraphic

这产生了一个合理的传真:

双正弦波

答案2

如果没有明显的简单方法,几乎​​总是可以实现缺失的功能。我想到的解决这个问题的方法基本上是:编写一个函数,生成到给定路径的偏移路径,该路径是给定路径上的时间函数;在给定路径的两侧生成两条这样的路径;连接它们;填充生成的形状。您可以找到代码(它是库的一部分,不幸的是,在这里引用它很长而且很乱)这里。一旦包含此库(输入 fiziko.mp),您就可以编写如下代码:

path p;
p := (0,0){dir(30)}..(5cm, 0)..{dir(30)}(10cm, 0);
draw brush (p)(1cm*sin(offsetPathLength*pi)) withcolor (0.75, 0.75, 1);
draw brush (p)(0.6cm*sin(offsetPathLength*pi)) withcolor (0.5, 0.5, 1);

其中函数“brush”实际上绘制可变宽度的线,它有两个参数:第一个是路径;第二个是一些任意函数,可以是“offsetPathLength”(路径上的弧长)或“offsetPathTime”(路径上的时间);并得到如下图片: 在此处输入图片描述

为了获得更多细节,您可能需要细分原始路径。它似乎可以与 ConTeXt 配合使用,但可能需要进行一些调整。

相关内容