function ball_in_a_bowl()

  % only MATLAB compatible

  % 1. create a video writer
  video = VideoWriter('out.avi', 'Uncompressed AVI');
  % 2. open the writer for writing
  open(video);

  
  % choose a dt equal to 1/30 of a second, for 30 fps movie
  dt = 0.03;
  t = 0:dt:20;

  % horizontal coordinates along the bowl
  % the bowl is given by h(x) = cos(x)
  l = linspace(0, 2 * pi, 1e2);

  % choose the initial position and velocity
  x = 0.1;
  v = 0.0;
  u = [x, v];

  % create a circle for plotting
  r = 0.1; % radius of the circle
  [cx, cy] = make_circle(); % unit circle

  % create the figure on which to plot movie frames
  figure(1);
  for i = 1:length(t)
    fprintf('Iteration %i\n', i);

    % 3. advance the simulation dt in time using ode45
    [~, U] = ode45(@(t, u) f(t, u), 0:dt:dt, u);
    u = U(end, :);
    x = u(1);
    v = u(2);

    % 4. plot a plot which is a movie frame
    clf();
    plot(l, cos(l), 'LineWidth', 3);
    hold on;
    fill(r * cx + x, r * cy + cos(x), 'r');

    % 5. make sure a ball is spherical (not squished in one dimension)
    axis('equal'); 
    % 6. make sure frames don't axis jumping around, ruins movie effect
    xlim([-0.1, 2 * pi]);
    ylim([-1.1, 1.1]);

    % 7. convert current figure to a movie frame
    frame = getframe(gcf());
    % 8. append the frame to the movie
    writeVideo(video, frame);
  end

  % 9. finalize saving the video
  close(video);
end

function [cx, cy] = make_circle()
  th = linspace(0, 2 * pi, 1e2);
  cx = cos(th);
  cy = sin(th);
end

function du = f(t, u)
  % extract states
  x = u(1);
  v = u(2);

  % get the slope of the cos(x) bowl; 
  % d/dx cos(x) = -sin(x)
  fx = -sin(x);
  ang = atan(fx); % angle from slope (standard geometry)

  % advance horizontal position adjusting for slope
  dx = v * cos(ang);
  
  % gravity and friction changing velocity
  g = 9.81;
  dv = -g * sin(ang) - 0.3 * v;

  % pack the derivatives of the states
  du = [dx, dv];
  % ensure the states are vertically stacked
  du = du(:);
end
