%%%% ========================================================================
%%%%  @MP-file{
%%%%     author              = "Ulrik Vieth",
%%%%     version             = "1.04",
%%%%     date                = "02 May 1995",
%%%%     time                = "11:25:28 MET",
%%%%     filename            = "interpol.mp",
%%%%     checksum            = "38415 89 464 3698",
%%%%     email               = "[email protected]",
%%%%     codetable           = "ISO/ASCII",
%%%%     keywords            = "MetaPost, graphs, interpolation",
%%%%     supported           = "yes",
%%%%     abstract            = "This file declares a new internal quantity
%%%%                            `interpolating' and modifies the `augment'
%%%%                            and `Mreadpath' routines of the MetaPost
%%%%                            graph package to construct a path from
%%%%                            data points using Bezier curves instead
%%%%                            instead of polygons (line segments) when
%%%%                            `interpolating' is set positive.
%%%%
%%%%                            Users of this package should be aware that
%%%%                            using this feature might lead to severe
%%%%                            distortions if the data isn't suitable.
%%%%                            It might be useful, however, when plotting
%%%%                            smooth functions evaluate numerically at
%%%%                            discrete intervals.
%%%%                            ",
%%%%     docstring           = "The checksum field above contains a CRC-16
%%%%                            checksum as the first value, followed by
%%%%                            the equivalent of the standard UNIX wc
%%%%                            (word count) utility output of lines,
%%%%                            words, and characters.  This is produced
%%%%                            by Robert Solovay's checksum utility.",
%%%%  }
%%%% ========================================================================

% Load the graph package if it hasn't been loaded already.
if unknown Gpaths:
 input graph
fi

newinternal interpolating;
interpolating:=0;

% Find the result of scanning path p and using macros tx and ty to adjust the
% x and y parts of each coordinate pair.  Boolean paramter c tells whether to
% force the result to be polygonal.
vardef Gscan_(expr p, c)(suffix tx, ty) =
 if (str tx="") and (str ty=""):  p
 else:
   Gpp_(point 0 of p, tx, ty)
   if path p:
     for t=1 upto length p:
       if c: if interpolating>0: .. else: -- fi
       else: ..controls Gpp_(postcontrol(t-1) of p, tx, ty)
         and Gpp_(precontrol t of p, tx, ty) ..
       fi
       Gpp_(point t of p, tx, ty)
     endfor
     if cycle p: &cycle fi
   fi
 fi
enddef;
vardef Gpp_(expr p)(suffix tx, ty) = (tx xpart p, ty ypart p) enddef;

% Read a path from file f and return it in Mlog form.  The path is terminated
% by blank line or EOF.
vardef Mreadpath(expr f) =
 interim warningcheck:=0;
 save s;
 gdata(f, s, if i>1: if interpolating>0: .. else: -- fi fi
     if s2="": (Mlog i, Mlog_str s1)
     else: (Mlog_str s1, Mlog_str s2) fi)
enddef;

% Append coordinates t to polygonal path @#.  The coordinates can be numerics,
% strings, or a single pair.
vardef augment@#(text t) =
 interim warningcheck := 0;
 if not path begingroup @# endgroup:
   Gerr(begingroup @# endgroup, "Cannot augment--not a path");
 else:
   def Gcma_= hide(def Gcma_=,enddef) enddef;
   if known @#:  @#:=@# if interpolating>0: .. else: -- fi else:  @#=  fi
   (for p=t:
      Gcma_ if string p: Mexp Mlog_str fi p
    endfor);
 fi
enddef;