使用 Metapost 绘制带切线的样条线

使用 Metapost 绘制带切线的样条线

我希望重现相同的图形。只是曲线并不完全符合预期,我想画一个环来追踪切线。

在此处输入图片描述

     \documentclass[border=5mm]{standalone}
     \usepackage{luatex85}
     \usepackage{luamplib}
     \begin{document}
     \mplibtextextlabel{enable}
     \begin{mplibcode}
      beginfig(1);
      pickup pencircle scaled 1bp;

     % parameters
     u = 1cm;
     ymin = 0;
     ymax = 12;
     xmin = 0;
     xmax = 8;

    % make a plain grid
    path xx, yy;
    xx = ((xmin,0) -- (xmax,0)) scaled u;
    yy = ((0,ymin) -- (0,ymax)) scaled u;

    drawoptions( withcolor .8 white);
    for i = ceiling ymin upto floor ymax: draw xx shifted (0,i*u); endfor
      for i = ceiling xmin upto floor xmax: draw yy shifted (i*u,0); endfor
      drawoptions( withcolor black);

   % make a curve
   z0=(u,u);
   z1=(3u,3u);
   z2=(5u,5u);
   z3=(7u,11u);
   path p;
   p = z0 {dir 14} .. z1{dir 63} .. z2{dir 0} .. z3{dir 79};
  draw p;

 % Specify a time along the path
   numeric ta[]; ta0 := 2;

 % Pick the point at that time
   pair a;     a := point ta0 of p;

 % Draw a tangent at a particular point
  path tangent; tangent := (-2cm,0) -- (2cm,0); 
  tangent := tangent rotated (angle direction ta0 of p) shifted a;
  draw tangent dashed evenly  withcolor blue;
  fill fullcircle scaled 3bp shifted a;

  endfig;
 \end{mplibcode}
 \end{document}

答案1

这是带有注释的版本。使用 进行编译lualatex

\documentclass[border=5mm]{standalone}
\usepackage{luatex85}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
beginfig(1);

    numeric u; u = 20;

    % grid
    drawoptions(withpen pencircle scaled 1/4 withcolor 3/4 white);
    z1 = (8, 12);
    for x = 0 upto x1: draw ((x,0) -- (x, y1)) scaled u; endfor
    for y = 0 upto y1: draw ((0,y) -- (x1, y)) scaled u; endfor
    drawoptions();

    % path ff is the one you want with "... = .. tension atleast 1 .."
    % path gg is just for comparison with the default tension

    path ff; ff = ((1,1) {4,1} ... (3,3) {1,2} ... (5,5) {1,0} ... (7,11) {1,5}) scaled u;
    path gg; gg = ((1,1) {4,1} .. (3,3) {1,2} .. (5,5) {1,0} .. (7,11) {1,5}) scaled u;

    % draw a tangent at each point along the path ff
    % draw these first so that they appear underneath the curve

    for t=0 upto length(ff):
        draw 
            (left--right) scaled 2u 
            rotated angle direction t of ff
            shifted point t of ff
            dashed withdots scaled 1/4
            withpen pencircle scaled 3/4
            withcolor 1/2[blue, white];
    endfor

    % now draw the curve(s)

    draw ff withcolor 3/4 red;
    draw gg dashed evenly withcolor 3/4 green;  % this is just for comparison

    % now label the points with letters and crosses.

    % First let's make a cross picture
    picture X; X = image(
        drawoptions(withpen pencircle scaled 1 withcolor 1/4[blue, white]);
        draw (left--right) scaled 2;
        draw (down--up) scaled 2;
        drawoptions();
    );

    % And finally use a list of strings to control the loop 
    % and the magical "incr" operator to increment the index
    % Note that we have mblibtextextlabel turned on, so each 
    % string is automatically wrapped in "TEX()" by the label macro
    numeric t;
    t = -1;
    for a = "$B$", "$E$", "$F$", "$L$":
        label.ulft(a, point incr t of ff);
        draw X shifted point t of ff;
    endfor

endfig;
\end{mplibcode}
\end{document}

在此处输入图片描述

请注意,绿色路径(具有默认张力)与 B..E..F 的红色路径相同。在这里,MP 无论如何都找到了一条很好的平滑曲线。但从 F..L 开始,默认张力意味着曲线会向右膨胀以避免急转弯。但增加张力会使曲线回到所需的线。本质上使用...而不是..意味着曲线将停留在由两个切线和连接两个点的线段形成的三角形内。

相关内容