I wish to reproduce the same figure. Only, the curve is not exactly the one expected and I want to make a loop to trace the tangents.

enter image description here

      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
   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;

  • 1
    You might want to get a look at the "spline" and "repere" package of MetaPost. – Franck Pastor Oct 19 at 12:35
  • 1
    You want to make the third segment of the path more "tense" -- so change .. to ... before z3 in your path. – Thruston Oct 19 at 21:37
  • 1
    And you don't need to calculate the angles to set the directions you can use a pairs in curly braces, like so path p; p = ((1,1) {4,1} .. (3,3) {1,2} .. (5,5) {1,0} ... (7, 11) {1, 5}) scaled u; – Thruston Oct 19 at 21:40
  • Thank you. Here is to draw the tangents using a loop : for i=0 upto 3: numeric ta[]; ta[i] = i; path tangent; tangent := (-5cm,0) -- (5cm,0); tangent := tangent rotated (angle direction ta[i] of p) shifted point ta[i] of p; draw tangent withcolor magenta; fill fullcircle scaled 3bp shifted point ta[i] of p ; endfor;To mark the points with a cross, I have to write a macro. – Fabrice Oct 20 at 8:51

Here's a version with some notes as comments. Compile with lualatex.


    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

    % 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):
            (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];

    % 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;

    % 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;


enter image description here

Note that the green path (with the default tension) is the same as the red path from B..E..F. Here MP has found a nice smooth curve anyway. But from F..L the default tension means that the curve balloons out to the right to avoid a sharp turn. But increasing the tension brings the curve back to the desired line. Essentially using ... instead of .. means the curve will stay within the triangle formed by the two tangents and the segment joining the two points.

  • Great ! Thank you for your help and your teaching. – Fabrice Oct 22 at 8:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.