// 使用自适应方法产生 y = f(x) 的图象 guide
guide plot(real f(real), real min, real max, int nplotpoints=10, int maxrec=7)
{
   if (nplotpoints < 2)
       nplotpoints = 2;
   // 描初始的 nplotpoints 个点,并估计函数变化幅度
   pair[] fpoints;
   real fmax = -infinity, fmin = infinity;
   for (int i = 0; i <= nplotpoints; ++i) {
       real x = min + i/nplotpoints * (max-min);
       pair z = (x, f(x));
       fmax = max(fmax, z.y);
       fmin = min(fmin, z.y);
       fpoints.push(z);
   }
   // 定义辅助的递归函数:在规定的递归次数之内,在两个样本点之间描新点
   // 误差 fuzz 达到函数变化幅度估计值的 1/500 为止
   // 这个误差值在一般屏幕显示上只有一两个像素
   real fuzz = max(0.002(fmax-fmin), realEpsilon);
   guide helper(int nrec, pair a, pair b)
   {
       if (nrec == 0)
           return b;
       pair mid = (a+b)/2;
       pair z = (mid.x, f(mid.x));
       if (abs(z.y-mid.y) < fuzz)
           return z -- b;
       else
           return helper(nrec-1, a, z) -- helper(nrec-1, z, b);
   }
   // 递归构造 guide
   guide g = fpoints[0];
   for (int i = 0; i < nplotpoints; ++i)
       g = g -- helper(maxrec, fpoints[i], fpoints[i+1]);
   return g;
}



//////////////////////////////////////////

real f(real x) {return 2sin(x^3);}
real min = -5.0, max = 5.0;

// 用自适应方法绘制函数 f(x)
guide g = scale(1cm)*plot(f, min, max);
draw(g, red+1pt);
for (int i = 0; i < size(g); ++i) {
   draw(point(g,i), blue+2pt);
}
write(size(g));


// 用 graph 模块的默认方法(均匀取点)绘制函数 f(x)
import graph;
guide h = shift(-5cm*I)*scale(1cm)*graph(f, min, max);
draw(h, orange+1pt);
for (int i = 0; i < size(h); ++i) {
   draw(point(h,i), blue+2pt);
}
write(size(h));