/********************************************************************
Attraktor Video
Plugin für Cinema Version 7
(c) Jürgen Meier (J.Meier@Dialup.Nacamar.de)
Version : 1.00
09.10.2001
*********************************************************************/


// Globale Variablen und Konstanten
   // Plugin ID Nummer
      const var cPluginID = 1006517;
   // Pluginname
      const var cPlugName = "Attraktor Video";
   // Pluginhilfstext
      const var cPlugHelp = "Erzeugt ein Video";
   // Anzahl der Attraktoren (Größe der Arrays)
      var N_Attraktor=9;
   // Aktueller Attraktor (Voreinstellung)
      var Aktuell=1;
   // Voreinstellung für das Videoformat
   // Masse des Videofensters
      var Breite=480;
      var Hoehe=360;
   // Videocodec
      var Vformat=1121;
   // Framerate
      var Framerate=12;
   // Berechnungsparameter
      var StartN=10;
      var StopN=25000;
   // Index für die Größe der Pixel
      var PIndex;
   // Konstanten für die Berechnung
      var k,a,b,c,d,t,s,co;
   // Variablen für die Berechnung
      var x,xa,y,z;
   // Pixelkoordinaten
      var xpixel,ypixel;
   // Abschwächung für Antialiasing
      var aa=0.8;
   // Schleifenvariablen
      var i,j;
   // Dialogvariable
      var gDial;

// ******************************************************************
// Signum Funktion
// ******************************************************************
   sign(x)
   {
   if (x>0) return 1;
      else {
       if (x==0) return 0;
           else return -1;
      }
   }


// ******************************************************************
// Wert x auf die Bitmap projezieren
// ******************************************************************
PixelX(x,xmin,xmax,breite)
{
   // Ermittlung des x Wertes durch Interpolation
      return (x-xmin)*(breite-1)/(xmax-xmin);
}

// ******************************************************************
// Wert y auf die Bitmap projezieren
// ******************************************************************
PixelY(y,ymin,ymax,hoehe)
{
   // Ermittlung des y Wertes durch Interpolation
      return (hoehe-1)-((y-ymin)*(hoehe-1)/(ymax-ymin));
}

// ******************************************************************
// Pixel auf die Bitmap setzen
// ******************************************************************
ZeichnePixel1(op,x,y,farbe)
{
   op->DrawPixel(int(x),int(y),farbe);
}

// ******************************************************************
// Pixel auf die Bitmap setzen
// ******************************************************************
ZeichnePixel2(op,x,y,farbe1,farbe2)
{
   // Hilfsvariable
      var f;
   // Pixel in der Mitte setzen
      op->DrawPixel(int(x),int(y),farbe1);

   // Rand zeichnen
      f=op->GetPixel(int(x)+1,int(y)+1);
      if (f!=vector(0,0,0)) {
          op->DrawPixel(int(x)+1,int(y)+1,farbe2);
      }

      f=op->GetPixel(int(x)+1,int(y));
      if (f!=vector(0,0,0)) {
          op->DrawPixel(int(x)+1,int(y),farbe2);
      }

      f=op->GetPixel(int(x)+1,int(y)-1);
      if (f!=vector(0,0,0)) {
          op->DrawPixel(int(x)+1,int(y)-1,farbe2);
      }

      f=op->GetPixel(int(x),int(y)+1);
      if (f!=vector(0,0,0)) {
          op->DrawPixel(int(x),int(y)+1,farbe2);
      }

      f=op->GetPixel(int(x),int(y)-1);
      if (f!=vector(0,0,0)) {
          op->DrawPixel(int(x),int(y)-1,farbe2);
      }

      f=op->GetPixel(int(x)-1,int(y)+1);
      if (f!=vector(0,0,0)) {
          op->DrawPixel(int(x)-1,int(y)+1,farbe2);
      }

      f=op->GetPixel(int(x)-1,int(y));
      if (f!=vector(0,0,0)) {
          op->DrawPixel(int(x)-1,int(y),farbe2);
      }

      f=op->GetPixel(int(x)-1,int(y)-1);
      if (f!=vector(0,0,0)) {
          op->DrawPixel(int(x)-1,int(y)-1,farbe2);
      }
}


// ******************************************************************
// Ableitung der Klasse MyDialog von GeDialog
// ******************************************************************
class MyDialog : GeDialog
{
   public:
   // Array für die Videonamen
      var Videoname;
   // Arrays für die Konstante k
      var kmin;
      var kmax;
      var Delta;
   // Arrays für die Bildausschnitte
      var xmin;
      var xmax;
      var ymin;
      var ymax;
   // Array für die Startwerte
      var x0;
      var y0;
   // Array für den Namen der Konstanten
      var Konstante;
   MyDialog();
   CreateLayout();
   Init();
   CoreMessage(vID,vMSG);
   Command(vID,vMSG);
}
// ******************************************************************
// Deklaration des Konstruktors
   MyDialog::MyDialog()
   {
    // Array für die Videonamen
       Videoname = new(array,N_Attraktor);
    // Arrays für die Konstante k
       kmin = new(array,N_Attraktor);
       kmax = new(array,N_Attraktor);
       Delta = new(array,N_Attraktor);
    // Arrays für die Bildausschnitte
       xmin = new(array,N_Attraktor);
       xmax = new(array,N_Attraktor);
       ymin = new(array,N_Attraktor);
       ymax = new(array,N_Attraktor);
    // Arrays für die Startwerte
       x0 = new(array,N_Attraktor);
       y0 = new(array,N_Attraktor);
    // Array für den Namen der Konstanten
       Konstante = new(array,N_Attraktor);
    // Konstruktor der parent class aufrufen
       super(cPluginID);
   }

// ******************************************************************
// Deklaration der Methode CreateLayout
   MyDialog::CreateLayout()
   {
   // Plugintitel setzen
      SetTitle(cPlugName);
   // Attraktortyp auswählen
      AddComboBox(9000,BFH_LEFT,300,0);
      AddItem(9000,9010,"Kaneko I Attraktor");
      AddItem(9000,9011,"Kaneko II Attraktor");
      AddItem(9000,9012,"Metzler Attraktor");
      AddItem(9000,9013,"Tinkerbell Attraktor");
      AddItem(9000,9014,"Ikeda Attraktor");
      AddItem(9000,9015,"Strick Attraktor a");
      AddItem(9000,9016,"Strick Attraktor b");
      AddItem(9000,9017,"Pickover Attraktor");
      AddItem(9000,9018,"Metz Attraktor");
   // Gruppe für die Videodaten
      AddGroupBeginV(100,BFH_SCALEFIT,2,"",0);
      {
         AddGroupBorder(BORDER_GROUP_IN);
         AddStaticText(0,BFH_LEFT,0,0," Videoformat",0);
         AddStaticText(0,BFH_LEFT,0,0," ",0);
         AddStaticText(0,BFH_LEFT,0,0," Auflösung x",0);
         AddEditNumber(1000,BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,0,0," Auflösung y",0);
         AddEditNumber(1001, BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,0,0," Format",0);
         AddComboBox(2000,BFH_LEFT,100,0);
         AddItem(2000,2010,"AVI klein");
         AddItem(2000,2011,"AVI gross");
         AddItem(2000,2012,"Quicktime klein");
         AddItem(2000,2013,"Quicktime gross");
         AddStaticText(0,BFH_LEFT,0,0," Dateiname",0);
         AddEditText(1002,BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,0,0," Frames / sec",0);
         AddEditNumber(1003,BFH_LEFT,100,0);
      }
      // Vertikal orientierte Gruppe schliessen
         AddGroupEnd();
   // Gruppe für die Videodaten
      AddGroupBeginV(100,BFH_SCALEFIT,2,"",0);
      {
         AddGroupBorder(BORDER_GROUP_IN);
         AddStaticText(0,BFH_LEFT,0,0," Konstante ",0);
         AddEditText(3003,BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,0,0," min",0);
         AddEditNumber(3000, BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,0,0," max",0);
         AddEditNumber(3001, BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,0,0," delta",0);
         AddEditNumber(3002, BFH_LEFT,100,0);
      }
      // Vertikal orientierte Gruppe schliessen
         AddGroupEnd();
   // Gruppe für den Bildausschnitt
      AddGroupBeginV(100,BFH_SCALEFIT,4,"",0);
      {
         AddGroupBorder(BORDER_GROUP_IN);
         AddStaticText(0,BFH_LEFT,0,0," Bildausschnitt",0);
         AddStaticText(0,BFH_LEFT,0,0," ",0);
         AddStaticText(0,BFH_LEFT,0,0," ",0);
         AddStaticText(0,BFH_LEFT,0,0," ",0);
         AddStaticText(0,BFH_LEFT,0,0," x-min",0);
         AddEditNumber(4000, BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,0,0," x-max",0);
         AddEditNumber(4001, BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,0,0," y-min",0);
         AddEditNumber(4002, BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,0,0," y-max",0);
         AddEditNumber(4003, BFH_LEFT,100,0);
      }
      // Vertikal orientierte Gruppe schliessen
         AddGroupEnd();
   // Gruppe für die Berechnungsparameter
      AddGroupBeginV(100,BFH_SCALEFIT,2,"",0);
      {
         AddGroupBorder(BORDER_GROUP_IN);
         AddStaticText(0,BFH_LEFT,0,0," Berechnungsparameter",0);
         AddStaticText(0,BFH_LEFT,0,0," ",0);
         AddStaticText(0,BFH_LEFT,0,0," Start n",0);
         AddEditNumber(5000, BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,0,0," Stop n",0);
         AddEditNumber(5001, BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,0,0," Pixelgröße",0);
         AddComboBox(6000,BFH_LEFT,100,0);
         AddItem(6000,6010,"klein");
         AddItem(6000,6011,"gross");
      }
      // Vertikal orientierte Gruppe schliessen
         AddGroupEnd();
   // Gruppe für Startbutton
      AddGroupBeginV(100,BFH_CENTER,2,"",0);
      {
         AddGroupBorder(BORDER_GROUP_IN);
         AddButton (7000,BFH_CENTER,200,0," Start Berechnung");
      }
      // Vertikal orientierte Gruppe schliessen
         AddGroupEnd();
   // Gruppe für die Anzahl der Frames
      AddGroupBeginV(100,BFH_SCALEFIT,4,"",0);
      {
         AddGroupBorder(BORDER_GROUP_IN);
         AddStaticText(0,BFH_LEFT,0,0," Frame ",0);
         AddEditNumber(8000, BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,0,0," von ",0);
         AddEditNumber(8001, BFH_LEFT,100,0);
      }
      // Vertikal orientierte Gruppe schliessen
         AddGroupEnd();
     return TRUE;
   }


// ******************************************************************
// Deklaration der Methode Init
   MyDialog::Init()
   {
   // Array für den Videonamen
      Videoname[0]="KanekoI";
      Videoname[1]="KanekoII";
      Videoname[2]="Metzler";
      Videoname[3]="Tinkerbell";
      Videoname[4]="Ikeda";
      Videoname[5]="Strick";
      Videoname[6]="Strick";
      Videoname[7]="Pickover";
      Videoname[8]="Metz";

   // Arrays für die Konstante k
      kmin[0]=0.4;            // Kaneko I
      kmin[1]=0.8;            // Kaneko II
      kmin[2]=0.50;           // Metzler
      kmin[3]=0.10;           // Tinkerbell
      kmin[4]=6.93;           // Ikeda
      kmin[5]=-0.6;           // Strick a
      kmin[6]=0.5;            // Strick b
      kmin[7]=1.6;            // Pickover
      kmin[8]=3.5;            // Metz

      kmax[0]=2.04;
      kmax[1]=1.23;
      kmax[2]=0.684;
      kmax[3]=0.601;
      kmax[4]=9.00;
      kmax[5]=0.57;
      kmax[6]=1.1;
      kmax[7]=3.5;
      kmax[8]=4.2;

   // Array für die Delta Werte
      Delta[0]=0.01;            // Kaneko I
      Delta[1]=0.002;           // Kaneko II
      Delta[2]=0.001;           // Metzler
      Delta[3]=0.002;           // Tinkerbell
      Delta[4]=0.01;            // Ikeda
      Delta[5]=0.005;           // Strick a
      Delta[6]=0.002;           // Strick b
      Delta[7]=0.005;           // Pickover
      Delta[8]=0.005;           // Metz

   // Arrays für den Bildausschnitt
      xmin[0]=-0.45;          // Kaneko I
      xmin[1]=-0.2;           // Kaneko II
      xmin[2]=-0.7;           // Metzler
      xmin[3]=-1.84;          // Tinkerbell
      xmin[4]=-1.4;           // Ikeda
      xmin[5]=-2.0;           // Strick
      xmin[6]=-2.0;           // Strick
      xmin[7]=-2.5;           // Pickover
      xmin[8]=0.0;            // Metz

      xmax[0]=0.95;
      xmax[1]=1.0;
      xmax[2]=2.9;
      xmax[3]=1.06;
      xmax[4]=2.4;
      xmax[5]=2.0;
      xmax[6]=2.0;
      xmax[7]=2.5;
      xmax[8]=200;

      ymin[0]=-0.45;         // Kaneko I
      ymin[1]=-0.2;          // Kaneko II
      ymin[2]=-0.7;          // Metzler
      ymin[3]=-0.6;          // Tinkerbell
      ymin[4]=-1.8;          // Ikeda
      ymin[5]=-1.25;         // Strick
      ymin[6]=-1.25;         // Strick
      ymin[7]=-2.0;          // Pickover
      ymin[8]=0.0;           // Metz

      ymax[0]=0.95;
      ymax[1]=1.0;
      ymax[2]=2.9;
      ymax[3]=1.58;
      ymax[4]=1.35;
      ymax[5]=1.25;
      ymax[6]=1.25;
      ymax[7]=2.0;
      ymax[8]=600;

   // Arrays für die Startwerte
      x0[0]=0.1;          // Kaneko I
      x0[1]=0.1;          // Kaneko II
      x0[2]=0.1;          // Metzler
      x0[3]=0.1;          // Tinkerbell
      x0[4]=0.4;          // Ikeda
      x0[5]=0.1;          // Strick
      x0[6]=0.1;          // Strick
      x0[7]=0.0;          // Pickover
      x0[8]=200;          // Metz

      y0[0]=0.1;
      y0[1]=0.1;
      y0[2]=0.8;
      y0[3]=0.0;
      y0[4]=0.5;
      y0[5]=0.1;
      y0[6]=0.1;
      y0[7]=0.2;
      y0[8]=60;

   // Array für den Namen der Konstanten
      Konstante[0] ="d";       // Kaneko I
      Konstante[1] ="d";       // Kaneko II
      Konstante[2] ="h";       // Metzler
      Konstante[3] ="b";       // Tinkerbell
      Konstante[4] ="d";       // Ikeda
      Konstante[5] ="a";       // Strick
      Konstante[6] ="b";       // Strick
      Konstante[7] ="a";       // Pickover
      Konstante[8] ="a";       // Metz

   // Attraktortyp
      SetItem(9000,9011);
   // Videoformat Breite
      SetInt(1000,Breite,1,4000,1);
   // Videoformat Hoehe
      SetInt(1001,Hoehe,1,4000,1);
   // Dateiname setzen
      SetString(1002,Videoname[Aktuell]);
   // Frames pro Sekunde setzen
      SetInt(1003,Framerate,1,50,1);
   // Voreinstellung Format
      SetItem(2000,2011);
   // Voreinstellung k min
      SetFloat(3000,kmin[Aktuell],-10000,10000,0.0001);
   // Voreinstellung k max
      SetFloat(3001,kmax[Aktuell],-10000,10000,0.0001);
   // Voreinstellung delta
      SetFloat(3002,Delta[Aktuell],0.000001,10000,0.001);
   // Voreinstellung Konstante
      SetString(3003,Konstante[Aktuell]);
   // Voreinstellung x min
      SetFloat(4000,xmin[Aktuell],-1000,1000,0.01);
   // Voreinstellung x min
      SetFloat(4001,xmax[Aktuell],-1000,1000,0.01);
   // Voreinstellung x min
      SetFloat(4002,ymin[Aktuell],-1000,1000,0.01);
   // Voreinstellung x min
      SetFloat(4003,ymax[Aktuell],-1000,1000,0.01);
   // Start N
      SetInt(5000,StartN,1,100000000,1);
   // Stop N
      SetInt(5001,StopN,1,100000000,1);
   // Voreinstellung Pixelgröße
      SetItem(6000,6010);
      PIndex=1;
   // Anzahl Frames
      SetInt(8001,int((kmax[Aktuell]-kmin[Aktuell])/Delta[Aktuell]),1,100000000,1);
   // Fenster für die Framezahlen sperren
      Enable(8000,FALSE);
      Enable(8001,FALSE);
   // Fenster für den Namen der Konstante sperren
      Enable(3003,FALSE);
   return TRUE;
   }

// ******************************************************************
// Deklaration der Methode CoreMessage
   MyDialog::CoreMessage(vID,vMSG)
   {
      switch (vID)
         {
            case NEW_DOCUMENT:
            case DOCUMENT_CHANGED:
            case NEW_ACTIVE_OBJECT:
            case ACTIVE_OBJECT_CHANGED:
               return TRUE;
               break;
         }
      return FALSE;
   }

// ******************************************************************
// Deklaration der Methode Command
   MyDialog::Command(vID,vMSG)
   {
   StopAllThreads();
   // Eingaben auswerten
      switch (vID)
      {
      // Videoformat Breite geändert
         case 1000 : {
                       Breite=GetInt(1000);
                       break;
                     }
      // Videoformat Hoehe geändert
         case 1001 : {
                       Hoehe=GetInt(1001);
                       break;
                     }
      // Framerate geändert
         case 1003 : {
                       Framerate=GetInt(1003);
                       break;
                     }
     // Videocodec geändert
         case 2000 : {
                       if (GetItem(2000)==2010) Vformat = 1120;
                       if (GetItem(2000)==2011) Vformat = 1121;
                       if (GetItem(2000)==2012) Vformat = 1123;
                       if (GetItem(2000)==2013) Vformat = 1124;
                       break;
                     }
      // kmin geändert
         case 3000 : {
                       kmin[Aktuell]=GetFloat(3000);
                       // Anzahl Frames aktualisieren
                          SetInt(8001,int((kmax[Aktuell]-kmin[Aktuell]) / Delta[Aktuell]),1,100000000,1);
                       break;
                     }
      // kmax geändert
         case 3001 : {
                       kmax[Aktuell]=GetFloat(3001);
                       // Anzahl Frames aktualisieren
                          SetInt(8001,int((kmax[Aktuell]-kmin[Aktuell]) /Delta[Aktuell]),1,100000000,1);
                       break;
                     }
      // Delta geändert
         case 3002 : {
                       Delta[Aktuell]=GetFloat(3002);
                       // Anzahl Frames aktualisieren
                          SetInt(8001,int((kmax[Aktuell]-kmin[Aktuell]) /Delta[Aktuell]),1,100000000,1);
                       break;
                     }
      // x min geändert
         case 4000 : {
                       xmin[Aktuell]=GetFloat(4000);
                       break;
                     }
      // x max geändert
         case 4001 : {
                       xmax[Aktuell]=GetFloat(4001);
                       break;
                     }
      // y min geändert
         case 4002 : {
                       ymin[Aktuell]=GetFloat(4002);
                       break;
                     }
      // y max geändert
         case 4003 : {
                       ymax[Aktuell]=GetFloat(4003);
                       break;
                     }
      // Start n geändert
         case 5000 : {
                       StartN=GetInt(5000);
                       break;
                     }
      // Stop n geändert
         case 5001 : {
                       StopN=GetInt(5001);
                       break;
                     }
      // Pixelgröße geändert
         case 6000 : {
                       if (GetItem(6000)==6010) PIndex=1;
                       if (GetItem(6000)==6011) PIndex=2;
                       break;
                     }
      // Attraktortyp geändert
         case 9000 : {
                       if (GetItem(9000)==9010)
                          {
                            Aktuell=0;
                          }
                       if (GetItem(9000)==9011) 
                          {
                            Aktuell=1;
                          }
                       if (GetItem(9000)==9012)
                          {
                            Aktuell=2;
                          }
                       if (GetItem(9000)==9013)
                          {
                            Aktuell=3;
                          }
                       if (GetItem(9000)==9014)
                          {
                            Aktuell=4;
                          }
                       if (GetItem(9000)==9015)
                          {
                            Aktuell=5;
                          }
                       if (GetItem(9000)==9016)
                          {
                            Aktuell=6;
                          }
                       if (GetItem(9000)==9017)
                          {
                            Aktuell=7;
                          }
                       if (GetItem(9000)==9018)
                          {
                            Aktuell=8;
                          }
                       SetString(1002,Videoname[Aktuell]);
                       SetFloat(3000,kmin[Aktuell],-10000,10000,0.0001);
                       SetFloat(3001,kmax[Aktuell],-10000,10000,0.0001);
                       SetFloat(3002,Delta[Aktuell],0.000001,10000,0.001);
                       SetString(3003,Konstante[Aktuell]);
                       SetFloat(4000,xmin[Aktuell],-1000,1000,0.01);
                       SetFloat(4001,xmax[Aktuell],-1000,1000,0.01);
                       SetFloat(4002,ymin[Aktuell],-1000,1000,0.01);
                       SetFloat(4003,ymax[Aktuell],-1000,1000,0.01);
                       SetInt(8001,int((kmax[Aktuell]-kmin[Aktuell]) / Delta[Aktuell]),1,100000000,1);
                       break;
                     }
      // Start Button gedrückt
         case 7000 : 
                    {
                       // 
                          var fn = GeGetStartupPath();
                       // Bitmap erzeugen
                          var bm = new(BaseBitmap,Breite,Hoehe);
                       // Movie Objekt erzeugen
                          var ms = new(MovieSaver);
                       // Container erzeugen
                          var bc = new(BaseContainer);
                       // Movie Datei erzeugen
                          fn->AddLast(stradd(GetString(1002),".avi"));
                          if (!ms->Open(fn,bm, GetInt(1003),Vformat, bc, FALSE)) return FALSE;
                       // Konstante auf Startwert setzen
                          k=kmin[Aktuell];
                       // Schleife für die Frames
                          for (i=0; i< int((kmax[Aktuell]-kmin[Aktuell]) /Delta[Aktuell]); i++)
                          {
                            // Aktuelle Framezahl in Fenster ausgeben
                               SetInt(8000,i,1,100000000,1);
                            // Stiftfarbe setzen
                               bm->SetPen(vector(1,1,1));
                            // Weisses Rechteck zeichnen
                               bm->DrawRect(0,0,Breite-1,Hoehe-1);
                            // Startwerte übergeben
                               xa=x0[Aktuell];
                               y=y0[Aktuell];
                               z=0;
                            // Schleife für die Berechnung durchlaufen
                               for (j=0;j<StopN;j++)
                               {
                                // Neue Koordinaten berechnen
// Auswahl des Attraktors
   switch (Aktuell)
   {
   // Kaneko I 
      case 0 : {
                  a=0.3;
                  x=a*xa+(1-a)*(1-k*y*y);
                  y=xa;
                  break;
               }
   // Kaneko II 
      case 1 : {
                  a=0.1;
                  x=a*xa+(1-a)*(1-k*abs(y));
                  y=xa;
                  break;
               }
   // Metzler
      case 2 : {
                  x=xa + k*(xa-xa*xa+y);
                  y=y + k*(y-y*y+xa);
                  break;
               }
   // Tinkerbell
      case 3 : {
                  a=0.9;
                  x= xa*xa - y*y + a* xa + k *y;
                  y=2*xa * y - 2*xa + 0.5 *y;
                  break;
               }
   // Ikeda
      case 4 : {
                  a=0.85;
                  b=0.90;
                  c=0.4;
                  // Hilfsvariablen berechnen
                     t=c-k/(1+xa*xa+y*y);
                     s=sin(t);
                     co=cos(t);
                  // Neue Koordinaten berechnen
                     x=a+b*(xa*co-y*s);
                     y=b*(xa*s+y*co);
                  break;
               }
   // Strick Attraktor Konstante a
      case 5 : {
                  b=1.1;
                  if (abs(xa)<0.5)
                     {
                       x=(2-k)*xa-b*y;
                       y=-b*xa+k*y;
                     }
                     else {
                       x=k*xa-b*y+(1-k)*sign(xa);
                       y=b*xa+k*y-b*sign(xa);
                     }
                  break;
               }
   // Strick Attraktor Konstante b
      case 6 : {
                  a=0.5;
                  if (abs(xa)<0.5)
                     {
                       x=(2-a)*xa-k*y;
                       y=-k*xa+a*y;
                     }
                     else {
                       x=a*xa-k*y+(1-a)*sign(xa);
                       y=k*xa+a*y-k*sign(xa);
                     }
                  break;
               }
   // Pickover Attraktor
      case 7 : {
                  b=0.43;
                  c=-0.65;
                  d=-2.43;
                  x = sin(k*y)-z*cos(b*xa);
                  y = z*sin(c*xa)-cos(d*y);
                  z = sin(xa);
                  break;
               }
   // Metz Attraktor
      case 8 : {
                  b=10;
                  x=k*xa*exp((1-sqrt(1+y))/b);
                  y=k*xa-x;
                  break;
               }
     }  // switch Aktuell
                                // Pixelposition berechnen
                                   xpixel=PixelX(x,xmin[Aktuell] ,xmax[Aktuell],Breite);
                                   ypixel=PixelY(y,ymin[Aktuell] ,ymax[Aktuell],Hoehe);
                                // Pixel zeichnen
                                   if (j>StartN) {
                                      if (PIndex==1) ZeichnePixel1(bm, xpixel, ypixel, vector(0,0,0));
                                      if (PIndex==2) ZeichnePixel2(bm, xpixel, ypixel, vector(0,0,0), vector(aa,aa,aa));
                                   }
                                // x Wert aktualisieren
                                   xa=x;
                               }
                            // Aktuellen Frame speichern
                               ms->AppendFrame(bm);
                            // Konstante aktualisieren
                               k=k+Delta[Aktuell];
                          }
                       // Video schliessen
                          ms->Close();
                    }
      }
      return TRUE;
   }


// ******************************************************************
// Ableitung der Klasse MyMenuPlugin von MenuPlugin
// ******************************************************************
class MyMenuPlugin : MenuPlugin
{     public:
          MyMenuPlugin();
          GetID();
          GetName();
          GetHelp();
          Execute(doc);
          RestoreLayout(secret);
}
// ******************************************************************
// Deklaration des Konstruktors
   MyMenuPlugin::MyMenuPlugin()
   { 
      super();
   }

// ******************************************************************
// Deklaration der Methode GetID
   MyMenuPlugin::GetID()
   {
      return cPluginID;
   }

// ******************************************************************
// Deklaration der Methode GetName
   MyMenuPlugin::GetName()
   {
       return cPlugName;
   }

// ******************************************************************
// Deklaration der Methode GetHelp
   MyMenuPlugin::GetHelp()
   {
       return cPlugHelp;
   }

// ******************************************************************
// Deklaration der Methode Execute
   MyMenuPlugin::Execute(doc)
   {
      if (!gDial)
         gDial=new(MyDialog);
     gDial->Open(TRUE,-1,-1);
   }
// ******************************************************************
// Deklaration der Methode RestoreLayout
   MyMenuPlugin::RestoreLayout(secret)
   {
      if (!gDial)
         gDial=new(MyDialog);
      gDial->RestoreLayout(secret);
   }

// ******************************************************************
main()
{     Register(MyMenuPlugin);
}

