/* -*-ePiX-*- */
#include "epix.h"
using namespace ePiX;

// parameters and an odd cubic
const double x0(0.4); // critical point
const double sqrt3(sqrt(3));

double f(double x)
{
  return 2*x*(x-sqrt3*x0)*(x+sqrt3*x0);
}

int main()
{
  picture(P(-2,-1), P(2,1), "6 x 3in");

  begin();

  degrees();

  // draw "ordinary" graph
  screen tmp(P(-1,-1), P(1,1));
  activate(tmp);

  // diagonal
  pen(Black(0.1));
  line(P(-1,-1), P(1,1));

  // two-headed arrow
  pen(Black(0.3));
  aarrow(P(0.4,0.6), P(0.6,0.4), 0.5);

  // axes and labels
  pen(Black());
  font_size("footnotesize");

  h_axis(8);
  v_axis(8);

  masklabel(P(1,0), "$x$");
  masklabel(P(0,1), "$y$");

  label(P(0.5,-0.5), "$y=f(x)$");

  label_angle(-90);
  label(P(-0.5,0.5), "$x=f^{-1}(y)$");

  // crop remaining elements
  tmp.set_crop();

  // a horizontal tangent line
  plain(Blue(1.4));
  tan_line(f, x0);

  // graphs that will be inverse branches
  plain(Red(1.4));
  plot(f, -1, -x0, 20);

  bold(Red());
  plot(f, -x0, x0, 20);

  plain(Red(1.4));
  plot(f, x0, 1, 20);

  inset(tmp, P(-2,-1), P(0,1));

  // flip plane over diagonal
  affine af;
  af.reflect(45).shift(P(0.25,0)); // compose affine maps
  inset(tmp.apply(af), P(0,-1), P(2,1));

  end();
}
