function draw_ball(center, radius, color)

  full_circle_arc = 360*64;
  up_left = center + radius * [-1, 1];
  ofg = xget("foreground");
  xset("foreground", color);
  xfarc(up_left(1),up_left(2),radius*2,radius*2,0,full_circle_arc);
  xset("foreground", ofg);

//end draw_ball

function clear_ball(center, radius)

  up_left = center + radius * [-1, 1];
  xclea(up_left(1),up_left(2),radius*2,radius*2);

//end clear_ball

function animate_rotor(ball_radius, rotor_center, scale, speed_rev, step_rev)

  anim_frame_delay = step_rev/speed_rev * 1000000; // microseconds
  step_rad  = step_rev*2*%pi;                      // radians per frame

  t=0;

  ball_center = rotor_center + [cos(t) sin(t)] .* scale; 

  draw_ball(ball_center, ball_radius, 2);

  while %T do

      t = t + step_rad;

      old_ball_center = ball_center;

      ball_center = rotor_center + [cos(t) sin(t)] .* scale; 

      xpause(anim_frame_delay);

      clear_ball(old_ball_center, ball_radius);

      draw_ball(ball_center, ball_radius, 2);

  end //while %T

//end animate_rotor

function bounce_demo

  expand_frame = 1.2;

  xset("window",1); xselect(); xclear();
  xstring(0., 0., ...
  [ ...
    'Animation of sinusoidal vibrator' ;
    ' '                                                ;
    'This animation looks a lot like a bouncing ball,' ;
    'but it is really showing the motion of a mass on' ;
    'an ideal spring. ""Ideal"" merely means that the' ;
    'spring pushes the mass back toward the center of' ;
    'the vibration with a force proportional to the'   ;
    'distance from the center.'                        ;
    ' '                                                ;
    'The path of the ball over time is a sine wave.'   ;
    ' '                                                ;
    'Most vibrations involved in the production and'   ;
    'detection of sound, including the vibrations of'  ;
    'small parts of musical instruments, vibrations of';
    'air molecules, vibrations of tiny sensors in the' ;
    'ears, etc., all behave very much like the vibration';
    'of an ideal spring.'
    ' '                                                ;
    'To control the animation, use the ""Stop"" and ""Resume""';
    'commands in the ""Control"" menu on the main Scilab';
    'window. Do not use ""Restart""---it will restart your';
    'whole Scilab session. To exit the animation, first';
    'stop it, then type ""quit"" to the main Scilab menu.'
  ]);

  xset("window",0); xselect(); xbasc();
  xtitle(['Animation of sinusoidal vibrator' ;
          'Use stop and resume on the Control menu' ;
          'in the main Scilab window to pause.' ;
          'When stopped, type quit to finish.']);
  square(-1,1,-1,1);
  plot2d(0,0,-1,"031"," ",[-1 -1 1 1]*expand_frame);

  animate_rotor(0.05, [0 0], [0 1], 0.3, 0.01);

//end bounce_demo

function rotor_demo

  expand_frame = 1.2;

  xset("window",1); xselect(); xclear();
  xstring(0., 0., ...
  [ ...
    'Animation of circular rotor' ;
    ' '                                                ;
    'To understand the motion of a vibrator in detail,';
    'it is best to first think of a rotor moving in a' ;
    'circle at a constant speed.'
    ' '                                                ;
    'To control the animation, use the ""Stop"" and ""Resume""';
    'commands in the ""Control"" menu on the main Scilab';
    'window. Do not use ""Restart""---it will restart your';
    'whole Scilab session. To exit the animation, first';
    'stop it, then type ""quit"" to the main Scilab menu.'
  ]);

  xset("window",0); xselect(); xbasc();
  xtitle(['Animation of circular rotor' ;
          'Use stop and resume on the Control menu' ;
          'in the main Scilab window to pause.' ;
          'When stopped, type quit to finish.']);
  square(-1,1,-1,1);
  plot2d(0,0,-1,"031"," ",[-1 -1 1 1]*expand_frame);

  animate_rotor(0.05, [0 0], [1 1], 0.3, 0.01);

//end rotor_demo

function animate_rotor_v_bounce(ball_radius, rotor_center, scale, ...
                                speed_rev, step_rev, v_bounce_channel)

  anim_frame_delay = step_rev/speed_rev * 1000000; // microseconds
  step_rad  = step_rev*2*%pi;                      // radians per frame

  t=0;
  r_ball_center = rotor_center + [cos(t) sin(t)];
  v_ball_center = [rotor_center(1) 0] + ...
                  [v_bounce_channel sin(t)] .* scale;
  draw_ball(r_ball_center, ball_radius, 2);
  draw_ball(v_ball_center, ball_radius, 5);

  while %T do

      t = t + step_rad;

      old_r_ball_center = r_ball_center;
      old_v_ball_center = v_ball_center;

      r_ball_center = rotor_center + [cos(t) sin(t)] .* scale; 
      v_ball_center = [rotor_center(1) 0] + ...
                      [v_bounce_channel sin(t)] .* scale; 

      xpause(anim_frame_delay);

      clear_ball(old_r_ball_center, ball_radius);
      clear_ball(old_v_ball_center, ball_radius);

      draw_ball(r_ball_center, ball_radius, 2);
      draw_ball(v_ball_center, ball_radius, 5);

  end //while %T

//end animate_rotor_v_bounce

function rotor_v_bounce_demo

  expand_frame = 1.4;

  xset("window",1); xselect(); xclear();
  xstring(0., 0., ...
  [ ...
    'Animation of circular rotor with vertical vibrator' ;
    ' '                                                ;
    'Now, look at the rotor and the vibrator together.';
    'Notice that the vertical vibrator tracks the height';
    'of the rotor. We say that the vibrator is the   ' ;
    'vertical component of the rotor, or the projection';
    'of the rotor on the vertical axis.'               ;
    ' '                                                ;
    'To control the animation, use the ""Stop"" and ""Resume""';
    'commands in the ""Control"" menu on the main Scilab';
    'window. Do not use ""Restart""---it will restart your';
    'whole Scilab session. To exit the animation, first';
    'stop it, then type ""quit"" to the main Scilab menu.'
  ]);

  xset("window",0); xselect(); xbasc();
  xtitle(['Circular rotor with vertical vibrator' ;
          'Use stop and resume on the Control menu' ;
          'in the main Scilab window to pause.' ;
          'When stopped, type quit to finish.']);
  square(-1,1,-1,1);
  plot2d(0,0,-1,"031"," ",[-1 -1 1 1]*expand_frame);

  animate_rotor_v_bounce(0.05, [0 0], [1 1], 0.3, 0.01, 1.2);

//end rotor_v_bounce_demo

function animate_rotor_vh_bounce(ball_radius, rotor_center, scale, ...
                                 speed_rev, step_rev, ...
                                 v_bounce_channel, h_bounce_channel)

  anim_frame_delay = step_rev/speed_rev * 1000000; // microseconds
  step_rad  = step_rev*2*%pi;                      // radians per frame

  t=0;
  r_ball_center = rotor_center + [cos(t) sin(t)];
  v_ball_center = [rotor_center(1) 0] + ...
                  [v_bounce_channel sin(t)] .* scale;
  h_ball_center = [0 rotor_center(2)] + ...
                  [cos(t) h_bounce_channel] .* scale;
  draw_ball(r_ball_center, ball_radius, 2);
  draw_ball(v_ball_center, ball_radius, 5);
  draw_ball(h_ball_center, ball_radius, 15);

  while %T do

      t = t + step_rad;

      old_r_ball_center = r_ball_center;
      old_v_ball_center = v_ball_center;
      old_h_ball_center = h_ball_center;

      r_ball_center = rotor_center + [cos(t) sin(t)] .* scale; 
      v_ball_center = [rotor_center(1) 0] + ...
                      [v_bounce_channel sin(t)] .* scale; 
      h_ball_center = [0 rotor_center(2)] + ...
                      [cos(t) h_bounce_channel] .* scale; 

      xpause(anim_frame_delay);

      clear_ball(old_r_ball_center, ball_radius);
      clear_ball(old_v_ball_center, ball_radius);
      clear_ball(old_h_ball_center, ball_radius);

      draw_ball(r_ball_center, ball_radius, 2);
      draw_ball(v_ball_center, ball_radius, 5);
      draw_ball(h_ball_center, ball_radius, 15);

  end //while %T

//end animate_rotor_vh_bounce

function rotor_vh_bounce_demo

  expand_frame = 1.4;

  xset("window",1); xselect(); xclear();
  xstring(0., 0., ...
  [ ...
    'Animation of circular rotor with'                 ;
    'vertical and horizontal vibrators'                ;
    ' '                                                ;
    'Here is a rotor with two vibrators, tracking the' ;
    'vertical and horizontal components. Notice the'   ;
    'alternation of motion between the vertical and'   ;
    'horizontal vibrators. The two motions are related';
    'in the same way as the sine (vertical) and cosine';
    'functions. We say that the two vibrators are'     ;
    '""90 degrees out of phase,"" or ""in quadrature.""';
    ' '                                                ;
    'To control the animation, use the ""Stop"" and ""Resume""';
    'commands in the ""Control"" menu on the main Scilab';
    'window. Do not use ""Restart""---it will restart your';
    'whole Scilab session. To exit the animation, first';
    'stop it, then type ""quit"" to the main Scilab menu.'
  ]);

  xset("window",0); xselect(); xbasc();
  xtitle(['Circular rotor with vert & horiz vibrators' ;
          'Use stop and resume on the Control menu' ;
          'in the main Scilab window to pause.' ;
          'When stopped, type quit to finish.']);
  square(-1,1,-1,1);
  plot2d(0,0,-1,"031"," ",[-1 -1 1 1]*expand_frame);

  animate_rotor_vh_bounce(0.05, [0 0], [1 1], 0.3, 0.01, 1.2, -1.2);

//end rotor_vh_bounce_demo

function animate_vh_bounce(ball_radius, rotor_center, scale, ...
                           speed_rev, step_rev, ...
                           v_bounce_channel, h_bounce_channel)

  anim_frame_delay = step_rev/speed_rev * 1000000; // microseconds
  step_rad  = step_rev*2*%pi;                      // radians per frame

  t=0;

  v_ball_center = [rotor_center(1) 0] + ...
                  [v_bounce_channel sin(t)] .* scale;
  h_ball_center = [0 rotor_center(2)] + ...
                  [cos(t), h_bounce_channel] .* scale;

  draw_ball(v_ball_center, ball_radius, 2);
  draw_ball(h_ball_center, ball_radius, 5);

  while %T do

      t = t + step_rad;

      old_v_ball_center = v_ball_center;
      old_h_ball_center = h_ball_center;

      v_ball_center = [rotor_center(1) 0] + ...
                      [v_bounce_channel sin(t)] .* scale; 
      h_ball_center = [0 rotor_center(2)] + ...
                      [cos(t) h_bounce_channel] .* scale; 

      xpause(anim_frame_delay);

      clear_ball(old_v_ball_center, ball_radius);
      clear_ball(old_h_ball_center, ball_radius);

      draw_ball(v_ball_center, ball_radius, 2);
      draw_ball(h_ball_center, ball_radius, 5);

  end //while %T

//end animate_vh_bounce

function do_nothing_machine_demo

 expand_frame = 1.4;

  xset("window",1); xselect(); xclear();
  xstring(0., 0., ...
  [ ...
    'Animation of traditional Do-Nothing Machine'      ;
    ' '                                                ;
    'This demo is mostly for fun. It shows two vibrators';
    'moving just like the vertical and horizontal'     ;
    'vibrators in the previous demo, but on tracks'    ;
    'that intersect as their midpoints. The alternation';
    'in motion (the phase difference) between the two' ;
    'vibrators keeps them from ever colliding. There'  ;
    'is an amusing wooden folk toy that generates this';
    'motion in two blocks sliding in slots, driven by' ;
    'a hand crank.'                                    ;
    ' '                                                ;
    'To control the animation, use the ""Stop"" and ""Resume""';
    'commands in the ""Control"" menu on the main Scilab';
    'window. Do not use ""Restart""---it will restart your';
    'whole Scilab session. To exit the animation, first';
    'stop it, then type ""quit"" to the main Scilab menu.'
  ]);

  xset("window",0); xselect(); xbasc();
  xtitle(['Traditional Do-Nothing Machine' ;
          'Use stop and resume on the Control menu' ;
          'in the main Scilab window to pause.' ;
          'When stopped, type quit to finish.']);
  square(-1,1,-1,1);
  plot2d(0,0,-1,"031"," ",[-1 -1 1 1]*expand_frame);

  animate_vh_bounce(0.05, [0 0], [1 1], 0.3, 0.01, 0, 0);

//end do_nothing_machine_demo

function do_nothing_rotor_demo

  expand_frame = 1.4;

  xset("window",1); xselect(); xclear();
  xstring(0., 0., ...
  [ ...
    'Animation of Do-Nothing Machine with rotor'       ;
    ' '                                                ;
    'Another one for fun, showing a do-nothing machine';
    'with a rotor.'                                    ;
    ' '                                                ;
    'To control the animation, use the ""Stop"" and ""Resume""';
    'commands in the ""Control"" menu on the main Scilab';
    'window. Do not use ""Restart""---it will restart your';
    'whole Scilab session. To exit the animation, first';
    'stop it, then type ""quit"" to the main Scilab menu.'
  ]);

  xset("window",0); xselect(); xbasc();
  xtitle(['Do-nothing Machine and rotor' ;
          'Use stop and resume on the Control menu' ;
          'in the main Scilab window to pause.' ;
          'When stopped, type quit to finish.']);
  square(-1,1,-1,1);
  plot2d(0,0,-1,"031"," ",[-1 -1 1 1]*expand_frame);

  animate_rotor_vh_bounce(0.05, [0 0], [1 1], 0.3, 0.01, 0, 0);

//end do_nothing_rotor_demo

function animate_2_rotors(ball_radius, rotor_center, scale_1, scale_2, ...
                          speed_rev, step_rev)

  anim_frame_delay = step_rev/speed_rev * 1000000; // microseconds
  step_rad  = step_rev*2*%pi;                      // radians per frame

  t=0;

  ball_1_center = rotor_center + [cos(t) sin(t)] .* scale_1;
  ball_2_center = rotor_center + [cos(t) sin(t)] .* scale_2;

  draw_ball(ball_1_center, ball_radius, 2);
  draw_ball(ball_2_center, ball_radius, 5);

  while %T do

      t = t + step_rad;

      old_ball_1_center = ball_1_center;
      old_ball_2_center = ball_2_center;

      ball_1_center = rotor_center + [cos(t) sin(t)] .* scale_1; 
      ball_2_center = rotor_center + [cos(t) sin(t)] .* scale_2; 

      xpause(anim_frame_delay);

      clear_ball(old_ball_1_center, ball_radius);
      clear_ball(old_ball_2_center, ball_radius);

      draw_ball(ball_1_center, ball_radius, 2);
      draw_ball(ball_2_center, ball_radius, 5);

  end //while %T

//end animate_2_rotors

function elliptical_rotor_demo

  expand_frame = 1.2;

  xset("window",1); xselect(); xclear();
  xstring(0., 0., ...
  [ ...
    'Animation of elliptical and circular rotors'      ;
    ' '                                                ;
    'Real physical vibrators are analyzed in terms of' ;
    'rotors, where one of the dimensions in the rotor' ;
    'plane presents the derivative (rate of change) of';
    'the value in the other dimension. In such a case,';
    'the motion of the rotor follows an ellipse, rather';
    'than a circle. The aspect ratio of the ellipse'   ;
    '(the ratio between the lengths of its two axes)'  ;
    'is proportional to the frequency of the rotor'    ;
    '(the number of revolutions in a unit of time).'   ;
    ' '                                                ;
    'This demonstration shows a circular rotor and an' ;
    'elliptical rotor, moving at the same frequency.'  ;
    'Notice that the speed of the elliptical rotor varies';
    'as it moves around the circle.'                   ;
    ' '                                                ;
    'To control the animation, use the ""Stop"" and ""Resume""';
    'commands in the ""Control"" menu on the main Scilab';
    'window. Do not use ""Restart""---it will restart your';
    'whole Scilab session. To exit the animation, first';
    'stop it, then type ""quit"" to the main Scilab menu.'
  ]);

  xset("window",0); xselect(); xbasc();
  xtitle(['Circular and elliptical rotors' ;
          'Use stop and resume on the Control menu' ;
          'in the main Scilab window to pause.' ;
          'When stopped, type quit to finish.']);
  square(-1,1,-2,2);
  plot2d(0,0,-1,"031"," ",[-1 -2 1 2]*expand_frame);

  animate_2_rotors(0.05, [0 0], [1 1], [1 2], 0.3, 0.01);

//end elliptical_rotor_demo

function animate_2_a_rotors(ball_radius, rotor_center, scale_1, scale_2, ...
                            speed_rev, step_rev)

  anim_frame_delay = step_rev/speed_rev * 1000000; // microseconds
  step_rad  = step_rev*2*%pi;                      // radians per frame
  max_scale = [min(scale_1(1),scale_2(1)) max(scale_1(2),scale_2(2))];

  t=0;

  ball_1_center = rotor_center + [cos(t) sin(t)] .* scale_1;
  ball_2_center = rotor_center + [cos(t) sin(t)] .* scale_2;

  draw_ball(ball_1_center, ball_radius, 2);
  draw_ball(ball_2_center, ball_radius, 5);

  xsegs([0 ball_1_center(1)],[0 ball_1_center(2)]);
  xsegs([0 ball_2_center(1)],[0 ball_2_center(2)]);

  while %T do

      t = t + step_rad;

      old_ball_1_center = ball_1_center;
      old_ball_2_center = ball_2_center;

      ball_1_center = rotor_center + [cos(t) sin(t)] .* scale_1; 
      ball_2_center = rotor_center + [cos(t) sin(t)] .* scale_2; 

      xpause(anim_frame_delay);

      xclea(rotor_center(1)-max_scale(1)-ball_radius*1.1, ...
            rotor_center(2)+max_scale(2)+ball_radius*1.1, ...
            2*(max_scale(1)+ball_radius*1.1), ...
            2*(max_scale(2)+ball_radius*1.1));

      draw_ball(ball_1_center, ball_radius, 2);
      draw_ball(ball_2_center, ball_radius, 5);

      xsegs([0 ball_1_center(1)],[0 ball_1_center(2)]);
      xsegs([0 ball_2_center(1)],[0 ball_2_center(2)]);

  end //while %T

//end animate_2_a_rotors

function elliptical_a_rotor_demo

  expand_frame = 1.2;

  xset("window",1); xselect(); xclear();
  xstring(0., 0., ...
  [ ...
    'Animation of elliptical and circular rotors'      ;
    'with arms'                                        ;
    ' '                                                ;
    'This demonstration shows the circular rotor and'  ;
    'elliptical rotor, with the rotational arms.'      ;
    'Notice that the angular speed of the elliptical'  ;
    'rotor varies, as well as the linear speed.'       ;
    ' '                                                ;
    'To control the animation, use the ""Stop"" and ""Resume""';
    'commands in the ""Control"" menu on the main Scilab';
    'window. Do not use ""Restart""---it will restart your';
    'whole Scilab session. To exit the animation, first';
    'stop it, then type ""quit"" to the main Scilab menu.'
  ]);

  xset("window",0); xselect(); xbasc();
  xtitle(['Circular and elliptical rotors with arms' ;
          'Use stop and resume on the Control menu' ;
          'in the main Scilab window to pause.' ;
          'When stopped, type quit to finish.']);
  square(-1,1,-2,2);
  plot2d(0,0,-1,"031"," ",[-1 -2 1 2]*expand_frame);

  animate_2_a_rotors(0.05, [0 0], [1 1], [1 2], 0.3, 0.01);

//end elliptical_a_rotor_demo

function animate_sum_2_a_rotors(ball_radius, rotor_center, ...
                                scale_1, scale_2, ...
                                speed_rev_1, step_rev_1, speed_rev_2)

  anim_frame_delay = step_rev_1/speed_rev_1 * 1000000; // microseconds
  step_rad  = step_rev_1*2*%pi;                       // radians per frame
  max_scale = [scale_1(1)+scale_2(1) scale_1(2)+scale_2(2)];

  speed_ratio = speed_rev_2 / speed_rev_1;

  t=0;

  ball_1_center =  rotor_center + [cos(t) sin(t)] .* scale_1;
  ball_2_center = ball_1_center + ...
                  [cos(t*speed_ratio) sin(t*speed_ratio)] .* scale_2;

  draw_ball(ball_1_center, ball_radius, 2);
  draw_ball(ball_2_center, ball_radius, 5);

  xsegs([0 ball_1_center(1)],[0 ball_1_center(2)]);
  xsegs([ball_1_center(1) ball_2_center(1)], ...
        [ball_1_center(2) ball_2_center(2)]);

  while %T do

      t = t + step_rad;

      old_ball_1_center = ball_1_center;
      old_ball_2_center = ball_2_center;

      ball_1_center =  rotor_center + [cos(t) sin(t)] .* scale_1; 
      ball_2_center = ball_1_center + ...
                      [cos(t*speed_ratio) sin(t*speed_ratio)] .* scale_2; 

      xpause(anim_frame_delay);

      xclea(rotor_center(1)-(max_scale(1)+ball_radius)*1.1, ...
            rotor_center(2)+(max_scale(2)+ball_radius)*1.1, ...
            2*(max_scale(1)+ball_radius)*1.1, ...
            2*(max_scale(2)+ball_radius)*1.1);

      draw_ball(ball_1_center, ball_radius, 2);
      draw_ball(ball_2_center, ball_radius, 5);

      xsegs([0 ball_1_center(1)],[0 ball_1_center(2)]);
      xsegs([ball_1_center(1) ball_2_center(1)], ...
            [ball_1_center(2) ball_2_center(2)]);

  end //while %T

//end animate_sum_2_a_rotors

function sum_2_a_rotors_demo

  expand_frame = 1.2;

  xset("window",1); xselect(); xclear();
  xstring(0., 0., ...
  [ ...
    'Animation of sum of two rotors, with rotational arms';
    ' '                                                ;
    'This demonstration shows the sum of two circular' ;
    'rotor motions, with the rotational arms. Notice how';
    'complex the motion appears, even though it is the';
    'sum of two simple circles.'                       ;
    ' '                                                ;
    'To control the animation, use the ""Stop"" and ""Resume""';
    'commands in the ""Control"" menu on the main Scilab';
    'window. Do not use ""Restart""---it will restart your';
    'whole Scilab session. To exit the animation, first';
    'stop it, then type ""quit"" to the main Scilab menu.'
  ]);

  xset("window",0); xselect(); xbasc();
  xtitle(['Sum of 2 rotors with arms' ;
          'Use stop and resume on the Control menu' ;
          'in the main Scilab window to pause.' ;
          'When stopped, type quit to finish.']);
  square(-1,1,-1,1);
  plot2d(0,0,-1,"031"," ",[-1.75 -1.75 1.75 1.75]*expand_frame);

  animate_sum_2_a_rotors(0.05, [0 0], [1 1], [0.6 0.6], 0.3, 0.01, 0.6);

//end sum_2_a_rotors_demo

function animate_sum_2_rotors(ball_radius, rotor_center, scale_1, scale_2, ...
                              speed_rev_1, step_rev_1, speed_rev_2)

  anim_frame_delay = step_rev_1/speed_rev_1 * 1000000; // microseconds
  step_rad  = step_rev_1*2*%pi;                       // radians per frame
  max_scale = [scale_1(1)+scale_2(1) scale_1(2)+scale_2(2)];

  speed_ratio = speed_rev_2 / speed_rev_1;

  t=0;

  ball_1_center =  rotor_center + [cos(t) sin(t)] .* scale_1;
  ball_2_center = ball_1_center + ...
                  [cos(t*speed_ratio) sin(t*speed_ratio)] .* scale_2;

  draw_ball(ball_2_center, ball_radius, 5);

  while %T do

      t = t + step_rad;

      old_ball_1_center = ball_1_center;
      old_ball_2_center = ball_2_center;

      ball_1_center =  rotor_center + [cos(t) sin(t)] .* scale_1; 
      ball_2_center = ball_1_center + ...
                      [cos(t*speed_ratio) sin(t*speed_ratio)] .* scale_2; 

      xpause(anim_frame_delay);

      xclea(rotor_center(1)-(max_scale(1)+ball_radius)*1.1, ...
            rotor_center(2)+(max_scale(2)+ball_radius)*1.1, ...
            2*(max_scale(1)+ball_radius)*1.1, ...
            2*(max_scale(2)+ball_radius)*1.1);

      draw_ball(ball_2_center, ball_radius, 5);

  end //while %T

//end animate_sum_2_rotors

function sum_2_rotors_demo

  expand_frame = 1.2;

  xset("window",1); xselect(); xclear();
  xstring(0., 0., ...
  [ ...
    'Animation of sum of two rotors'                   ;
    ' '                                                ;
    'Without the rotational arms, the sum of two circular';
    'rotor motions is quite confusing. I doubt that many';
    'people could recognize this motion and analyze it';
    'by eye.'                                          ;
    ' '                                                ;
    'To control the animation, use the ""Stop"" and ""Resume""';
    'commands in the ""Control"" menu on the main Scilab';
    'window. Do not use ""Restart""---it will restart your';
    'whole Scilab session. To exit the animation, first';
    'stop it, then type ""quit"" to the main Scilab menu.'
  ]);

  xset("window",0); xselect(); xbasc();
  xtitle(['Sum of 2 rotors' ;
          'Use stop and resume on the Control menu' ;
          'in the main Scilab window to pause.' ;
          'When stopped, type quit to finish.']);
  square(-1,1,-1,1);
  plot2d(0,0,-1,"031"," ",[-1.75 -1.75 1.75 1.75]*expand_frame);

  animate_sum_2_rotors(0.05, [0 0], [1 1], [0.6 0.6], 0.3, 0.01, 0.6);

//end sum_2_rotors_demo

function sum_2_bounce_demo

  expand_frame = 1.2;

  xset("window",1); xselect(); xclear();
  xstring(0., 0., ...
  [ ...
    'Animation of sum of two rotors: vertical component';
    ' '                                                ;
    'Looking at only the vertical component, the sum of';
    'two rotor motions is even more opaque.'           ;
    ' '                                                ;
    'To control the animation, use the ""Stop"" and ""Resume""';
    'commands in the ""Control"" menu on the main Scilab';
    'window. Do not use ""Restart""---it will restart your';
    'whole Scilab session. To exit the animation, first';
    'stop it, then type ""quit"" to the main Scilab menu.'
  ]);

  xset("window",0); xselect(); xbasc();
  xtitle(['Sum of 2 rotors: vertical component' ;
          'Use stop and resume on the Control menu' ;
          'in the main Scilab window to pause.' ;
          'When stopped, type quit to finish.']);
  square(-1,1,-1,1);
  plot2d(0,0,-1,"031"," ",[-1.75 -1.75 1.75 1.75]*expand_frame);

  animate_sum_2_rotors(0.05, [0 0], [0 1], [0 0.6], 0.3, 0.01, 0.6);

//end sum_2_bounce_demo

function animate_sum_3_a_rotors(ball_radius, rotor_center, ...
                                scale_1, scale_2, scale_3, ...
                                speed_rev_1, step_rev_1, ...
                                speed_rev_2, speed_rev_3)

  anim_frame_delay = step_rev_1/speed_rev_1 * 1000000; // microseconds
  step_rad  = step_rev_1*2*%pi;                       // radians per frame
  max_scale = [scale_1(1)+scale_2(1)+scale_3(1) ...
               scale_1(2)+scale_2(2)+scale_3(2)];

  speed_ratio_2 = speed_rev_2 / speed_rev_1;
  speed_ratio_3 = speed_rev_3 / speed_rev_1;

  t=0;

  ball_1_center =  rotor_center + [cos(t) sin(t)] .* scale_1;
  ball_2_center = ball_1_center + ...
                  [cos(t*speed_ratio_2) sin(t*speed_ratio_2)] .* scale_2;
  ball_3_center = ball_2_center + ...
                  [cos(t*speed_ratio_3+%pi) sin(t*speed_ratio_3+%pi)] ...
                  .* scale_3;

  draw_ball(ball_1_center, ball_radius, 2);
  draw_ball(ball_2_center, ball_radius, 5);
  draw_ball(ball_3_center, ball_radius, 15);

  xsegs([0 ball_1_center(1)],[0 ball_1_center(2)]);
  xsegs([ball_1_center(1) ball_2_center(1)], ...
        [ball_1_center(2) ball_2_center(2)]);
  xsegs([ball_2_center(1) ball_3_center(1)], ...
        [ball_2_center(2) ball_3_center(2)]);

  while %T do

      t = t + step_rad;

      old_ball_1_center = ball_1_center;
      old_ball_2_center = ball_2_center;
      old_ball_3_center = ball_3_center;

      ball_1_center =  rotor_center + [cos(t) sin(t)] .* scale_1; 
      ball_2_center = ball_1_center + ...
                      [cos(t*speed_ratio_2) sin(t*speed_ratio_2)] .* scale_2; 
      ball_3_center = ball_2_center + ...
                      [cos(t*speed_ratio_3+%pi) sin(t*speed_ratio_3+%pi)] ...
                      .* scale_3;

      xpause(anim_frame_delay);

      xclea(rotor_center(1)-(max_scale(1)+ball_radius)*1.1, ...
            rotor_center(2)+(max_scale(2)+ball_radius)*1.1, ...
            2*(max_scale(1)+ball_radius)*1.1, ...
            2*(max_scale(2)+ball_radius)*1.1);

      draw_ball(ball_1_center, ball_radius, 2);
      draw_ball(ball_2_center, ball_radius, 5);
      draw_ball(ball_3_center, ball_radius, 15);

      xsegs([0 ball_1_center(1)],[0 ball_1_center(2)]);
      xsegs([ball_1_center(1) ball_2_center(1)], ...
            [ball_1_center(2) ball_2_center(2)]);
      xsegs([ball_2_center(1) ball_3_center(1)], ...
            [ball_2_center(2) ball_3_center(2)]);

  end //while %T

//end animate_sum_3_a_rotors

function sum_3_a_rotors_demo

  expand_frame = 1.2;

  xset("window",1); xselect(); xclear();
  xstring(0., 0., ...
  [ ...
    'Animation of sum of three rotors, with arms'      ;
    ' '                                                ;
    'To control the animation, use the ""Stop"" and ""Resume""';
    'commands in the ""Control"" menu on the main Scilab';
    'window. Do not use ""Restart""---it will restart your';
    'whole Scilab session. To exit the animation, first';
    'stop it, then type ""quit"" to the main Scilab menu.'
  ]);

  xset("window",0); xselect(); xbasc();
  xtitle(['Sum of 3 rotors with arms' ;
          'Use stop and resume on the Control menu' ;
          'in the main Scilab window to pause.' ;
          'When stopped, type quit to finish.']);
  square(-1,1,-1,1);
  plot2d(0,0,-1,"031"," ",[-2.1 -2.1 2.1 2.1]*expand_frame);

  animate_sum_3_a_rotors(0.05, [0 0], [1 1], [0.6 0.6], [0.5 0.5], ...
                         0.3, 0.01, 0.6, 0.9);

//end sum_3_a_rotors_demo

function animate_sum_3_rotors(ball_radius, rotor_center, ...
                              scale_1, scale_2, scale_3, ...
                              speed_rev_1, step_rev_1, ...
                              speed_rev_2, speed_rev_3)

  anim_frame_delay = step_rev_1/speed_rev_1 * 1000000; // microseconds
  step_rad  = step_rev_1*2*%pi;                       // radians per frame
//  max_scale = [scale_1(1)+scale_2(1)+scale_3(1) ...
//               scale_1(2)+scale_2(2)+scale_3(2)];

  speed_ratio_2 = speed_rev_2 / speed_rev_1;
  speed_ratio_3 = speed_rev_3 / speed_rev_1;

  t=0;

  ball_1_center =  rotor_center + [cos(t) sin(t)] .* scale_1;
  ball_2_center = ball_1_center + ...
                  [cos(t*speed_ratio_2) sin(t*speed_ratio_2)] .* scale_2;
  ball_3_center = ball_2_center + ...
                  [cos(t*speed_ratio_3+%pi) sin(t*speed_ratio_3+%pi)] ...
                  .* scale_3;

  draw_ball(ball_3_center, ball_radius, 15);

  while %T do

      t = t + step_rad;

      old_ball_1_center = ball_1_center;
      old_ball_2_center = ball_2_center;
      old_ball_3_center = ball_3_center;

      ball_1_center =  rotor_center + [cos(t) sin(t)] .* scale_1; 
      ball_2_center = ball_1_center + ...
                      [cos(t*speed_ratio_2) sin(t*speed_ratio_2)] .* scale_2; 
      ball_3_center = ball_2_center + ...
                      [cos(t*speed_ratio_3+%pi) sin(t*speed_ratio_3+%pi)] ...
                      .* scale_3;

      xpause(anim_frame_delay);

      clear_ball(old_ball_3_center, ball_radius);

      draw_ball(ball_3_center, ball_radius, 15);

  end //while %T

//end animate_sum_3_a_rotors

function sum_3_rotors_demo

  expand_frame = 1.2;

  xset("window",1); xselect(); xclear();
  xstring(0., 0., ...
  [ ...
    'Animation of sum of three rotors'                 ;
    ' '                                                ;
    'To control the animation, use the ""Stop"" and ""Resume""';
    'commands in the ""Control"" menu on the main Scilab';
    'window. Do not use ""Restart""---it will restart your';
    'whole Scilab session. To exit the animation, first';
    'stop it, then type ""quit"" to the main Scilab menu.'
  ]);

  xset("window",0); xselect(); xbasc();
  xtitle(['Sum of 3 rotors' ;
          'Use stop and resume on the Control menu' ;
          'in the main Scilab window to pause.' ;
          'When stopped, type quit to finish.']);
  square(-1,1,-1,1);
  plot2d(0,0,-1,"031"," ",[-1.75 -1.75 1.75 1.75]*expand_frame);

  animate_sum_3_rotors(0.05, [0 0], [1 1], [0.6 0.6], [0.5 0.5], ...
                         0.3, 0.01, 0.6, 0.9);

//end sum_3_rotors_demo

function sum_3_bounce_demo

  expand_frame = 1.2;

  xset("window",1); xselect(); xclear();
  xstring(0., 0., ...
  [ ...
    'Animation of sum of three rotors: vertical component';
    ' '                                                ;
    'To control the animation, use the ""Stop"" and ""Resume""';
    'commands in the ""Control"" menu on the main Scilab';
    'window. Do not use ""Restart""---it will restart your';
    'whole Scilab session. To exit the animation, first';
    'stop it, then type ""quit"" to the main Scilab menu.'
  ]);

  xset("window",0); xselect(); xbasc();
  xtitle(['Sum of 3 rotors: vertical component' ;
          'Use stop and resume on the Control menu' ;
          'in the main Scilab window to pause.' ;
          'When stopped, type quit to finish.']);
  square(-1,1,-1,1);
  plot2d(0,0,-1,"031"," ",[-1.75 -1.75 1.75 1.75]*expand_frame);

  animate_sum_3_rotors(0.05, [0 0], [0 1], [0 0.6], [0 0.5], ...
                         0.3, 0.01, 0.6, 0.9);

//end sum_3_bounce_demo
