program ellipsen;
uses crt, graph;

const radx=150;                              {Horizontal radius 150}
      faktor=1;                              {Detail factor}

var gd, gm, i, j, k : integer;
    mpx, mpy, rady : integer;
    winkel2 : real;
    a, b, c, d : real;
    pktfeld : array[0..radx*faktor] of record
                                    x, y : longint;
                                    winkel : real;
                                    radius : real;
                                  end;

procedure bild;
  begin
    mpx:=320; mpy:=240; rady:=100;           {Start with screen center and
                                              vertical radius 100}
    for i:= 0 to radx*faktor do              {Init ellipse points saving}
      begin
        pktfeld[i].x:=0;
        pktfeld[i].y:=0;
        pktfeld[i].winkel:=0;
        pktfeld[i].radius:=0;
      end;
    for i:=radx*faktor downto 0 do           {Calculate each ellipse points}
      begin
        a:=(i/faktor)*(i/faktor)*rady*rady/(radx*radx);
        b:=rady*rady;
        c:=(b-a);
        if c<0 then d:=sqrt(-c) else d:=sqrt(c);
        if c<0 then d:=-d;
        with pktfeld[i] do
          begin
            y:=round(d);                     {Save each point}
            x:=round(i/faktor);
            radius:=sqrt(x*x+y*y);           {Distance to center}
            if x>0 then winkel:=arctan(y/x)  {angle of each point to
                                              horizontal}
                   else winkel:=90*Pi/180;   {angle 90 degrees}
          end;
      end;
   {ellipse(mpx, mpy, 0, 360, radx, rady);}
   for i:=0 to radx*faktor do                {Draw first red ellipse}
     begin
       putpixel(mpx+pktfeld[i].x, mpy+pktfeld[i].y, 4);
       putpixel(mpx-pktfeld[i].x, mpy-pktfeld[i].y, 4);
       putpixel(mpx+pktfeld[i].x, mpy-pktfeld[i].y, 4);
       putpixel(mpx-pktfeld[i].x, mpy+pktfeld[i].y, 4);
     end;
   for j:=0 to 35 do                         {Full rotation with
                                              10 degree steps}
   for k:=0 to 3 do                          {For each 4 parts of ellipse}
     begin
       if (k=0) or (k=2) then                {right top and left bottom}
       for i:=0 to radx*faktor do            {of ellipse, each point}
         begin
           with pktfeld[i] do
             begin
               if k=0 then winkel:=winkel+10*Pi/180;
                                             {Next 10 degrees step}
               x:=round((radius*cos(winkel+(Pi/2)*k)));
                                             {Rotate with winkel + 0 or 180ø}
               y:=round((radius*sin(winkel+(Pi/2)*k)));
               putpixel(mpx+pktfeld[i].x, mpy+pktfeld[i].y, random(14)+1);
                                             {Draw points}
             end;
         end;
       if (k=1) or (k=3) then                {left top and right bottom}
       for i:=0 to radx*faktor do            {of ellipse, each point}
         begin
           with pktfeld[i] do
             begin
               x:=round((radius*cos(winkel+(Pi/2)*k)));
                                             {Rotate with winkel + 0 or 180ø}
               y:=round((radius*sin(winkel+(Pi/2)*k)));
               putpixel(mpx-pktfeld[i].x, mpy+pktfeld[i].y, random(14)+1);
             end;                            {Draw points}
         end;
      if keypressed then exit;
      if k=3 then delay(500);                {Wait after 1 full ellipse}
      if (k=3) and (j<35) then cleardevice;  {Clear screen when waiting}
      for i:=0 to radx*faktor do             {Draw second ellipse with
                                              random colors}
        begin
          putpixel(mpx+pktfeld[i].x, mpy+pktfeld[i].y, random(14)+1);
          putpixel(mpx-pktfeld[i].x, mpy-pktfeld[i].y, random(14)+1);
          putpixel(mpx+pktfeld[i].x, mpy-pktfeld[i].y, random(14)+1);
          putpixel(mpx-pktfeld[i].x, mpy+pktfeld[i].y, random(14)+1);
        end;
    end;
  end;

begin
  gd:=9; gm:=2;
  initgraph(gd, gm, 'd:\tp\bgi');            {Load graphic driver}
  cleardevice;                               {Clear screen}
  repeat
    bild;                                    {Draw ellipses}
    delay(10000);                            {Wait after one rotation}
  until keypressed;                          {End with any key}
  closegraph;                                {Back to text mode}
end.
