kramann.info
© Guido Kramann

Login: Passwort:










7.2 Erzeugen von Animationen mit Hilfe von Scilab

  • Um das Zeitverhalten eines COACH-Vehikels zu verstehen und noch viel mehr, das eines ganzen Schwarms, drängt es sich auf, die entsprechenden Bewegungen im Raum zu animieren.
  • Egal wie man das macht, es erfordert immer ein gewisses Maß an Einarbeitung und Aufwand.
  • Eine Animation mit Scilab umzusetzen, ist noch relativ unaufwändig.
  • Um hier etwas die Hürden zu nehmen, sollen in drei Beispielen die Möglichkeiten aufgezeigt werden.
  • Die Beispiele werden innerhalb der Vorlesung erläutert werden.
Scilab-Animation - Beispiel 1 - gleitendes rotes Rechteck
//wanderndes rotes Rechteck
function grafikmodus_initialisieren()
    drawlater();  //neues Grafikobjekt zunächst in einen Puffer schreiben
    scf(1);       //Grafikfigur mit id=1 erzeugen
    clf();        //aktuelles Grafikfenster löschen
    h=gcf();      //liefert Handle (Objekt) des GUI
    h.figure_size = [600 600];       //Aktuelles Grafikobjekt auf 600x600 Pixel Größe festlegen
    h.children.isoview='on';         //Ausdehnungen in x- und y-Richtung gleich
    h.children.margins = [0,0,0,0];  //Keinen Bildrand lassen
    //Koordinaten des oberen linken und unteren rechten Bildpunktes. (?)
    //Entsprechend wird die Darstellung skaliert.
    xmin=-12;
    ymin=-12; 
    xmax=12; 
    ymax=12;
    h.children.data_bounds=[xmin,xmax,ymin,ymax]; 
    h.pixmap = "on"; //Mit einem Puffer für das aktuell gezeichnete Bild arbeiten
endfunction
function animieren()
    xe = [0,2,2,0,0]; //Rechteckumriß als Polygon, x-Koordinaten
    ye = [0,0,5,5,0]; //Rechteckumriß als Polygon, y-Koordinaten
    xfpoly(xe,ye,1);  //Rechteck in den Puffer zeichnen
    a=get("current_axes");         //Wurzelobjekt im Hierarchiebaum der Grafikobjekte holen
    a.children(1).background=5;    //erstes Kindobjekt (das Rechteck) wählen und rot färben
    realtimeinit(0.2);             //Realtimemodus setzen und Animationsgeschwindigkeit festlegen
    for tt=0:1:100                 //Schleife, in der die Animationsschritte durchgeführt werden
        t=tt*0.1;
        realtime(t);               //aktuelle Zeit zu aktuellen Ereignissen setzen
        xe = [0+t,2+t,2+t,0+t,0+t];//Translation für x-Koordinaten des Polygons festlegen 
        ye = [0,0,5,5,0]; 
        a.children(1).data = [xe',ye']; //Polygonpunkte in Objekt schreiben
        draw(a);                        //Gesamte Grafikobjekte in Puffer zeichnen
        show_pixmap();                  //...und darstellen
    end
    h.pixel_drawing_mode='copy';        //Mode: Gesamtes fertiges Bild nach Zeichnen im Puffer anzeigen
endfunction
grafikmodus_initialisieren();
animieren();

Code 7.2-1: 001_animation_wanderndes_rechteck.sce - Scilab-Animations-Skript.

Scilab-Animation - Beispiel 2 - rotierend gleitendes rotes Rechteck mit Koordinatentransformationsfunktionen
//wanderndes rotes Rechteck
function grafikmodus_initialisieren()
    drawlater();  //neues Grafikobjekt zunächst in einen Puffer schreiben
    scf(1);       //Grafikfigur mit id=1 erzeugen
    clf();        //aktuelles Grafikfenster löschen
    h=gcf();      //liefert Handle (Objekt) des GUI
    h.figure_size = [900 900];       //Aktuelles Grafikobjekt auf 600x600 Pixel Größe festlegen
    h.children.isoview='on';         //Ausdehnungen in x- und y-Richtung gleich
    h.children.margins = [0,0,0,0];  //Keinen Bildrand lassen
    //Koordinaten des oberen linken und unteren rechten Bildpunktes. (?)
    //Entsprechend wird die Darstellung skaliert.
    xmin=-12;
    ymin=-12; 
    xmax=12; 
    ymax=12;
    h.children.data_bounds=[xmin,xmax,ymin,ymax]; 
    h.pixmap = "on"; //Mit einem Puffer für das aktuell gezeichnete Bild arbeiten
endfunction
//Funktion zur Transformation eines Punktes auf einem Körper in das Inertialkoordinatensystem (ebene Transformation).
//Auf dem Körper hat der Punkt die Koordinaten (x_koerper,y_koerper)
//Der Körper selbst hat im Inertialsystem die Koordinaten x,y und ist im phi verdreht.
function punkt = berechnePunkt(x_koerper,y_koerper,x,y,phi)
    punkt =  [x;y] + [cos(phi),-sin(phi);sin(phi),cos(phi)]*[x_koerper;y_koerper];
endfunction
//Alle Umrißpunkte eines Körpers entsprechend seiner aktuellen Lage bestimmen:
//Hier sind x_koerper,y_koerper Zeilen-Vektoren, die alle x- bzw. y-Koordinaten des Körperumrisses enthalten
function punkte = berechneUmriss(x_koerper,y_koerper,x,y,phi)    
    gr = size(x_koerper);
    spalten = gr(2);
    punkte = zeros(2,gr(2));
    for i=1:spalten
        punkte(:,i) =  berechnePunkt(x_koerper(1,i),y_koerper(1,i),x,y,phi);
    end
endfunction
function animieren(t,x,y,phi)
    xe = [0,2,2,0,0]; //Rechteckumriß als Polygon, x-Koordinaten
    ye = [0,0,5,5,0]; //Rechteckumriß als Polygon, y-Koordinaten
    umriss = berechneUmriss(xe,ye,x(1),y(1),phi(1));
    xfpoly(umriss(1,:),umriss(2,:),1);  //Rechteck in den Puffer zeichnen
    a=get("current_axes");         //Wurzelobjekt im Hierarchiebaum der Grafikobjekte holen
    a.children(1).background=5;    //erstes Kindobjekt (das Rechteck) wählen und rot färben
    realtimeinit(1);             //Realtimemodus setzen und Animationsgeschwindigkeit festlegen
    gr=size(t);
    zeitschritte = gr(2);
    for index=1:1:zeitschritte     //Schleife, in der die Animationsschritte durchgeführt werden
        realtime(t(index));               //aktuelle Zeit zu aktuellen Ereignissen setzen
        umriss = berechneUmriss(xe,ye,x(index),y(index),phi(index));
        a.children(1).data = [umriss(1,:)',umriss(2,:)']; //Polygonpunkte in Objekt schreiben
        draw(a);                        //Gesamte Grafikobjekte in Puffer zeichnen
        show_pixmap();                  //...und darstellen
    end
    h.pixel_drawing_mode='copy';        //Mode: Gesamtes fertiges Bild nach Zeichnen im Puffer anzeigen
endfunction
t=0:0.01:3;
phi=2*%pi*t;
x=t*2;
y=t;
grafikmodus_initialisieren();
animieren(t,x,y,phi);

Code 7.2-2: 002_animation_rotation.sce - Scilab-Animations-Skript.

Scilab-Animation - Beispiel 3 - mehrere rotierend gleitende Körper
//wanderndes rotes Rechteck
function grafikmodus_initialisieren()
    drawlater();  //neues Grafikobjekt zunächst in einen Puffer schreiben
    scf(1);       //Grafikfigur mit id=1 erzeugen
    clf();        //aktuelles Grafikfenster löschen
    h=gcf();      //liefert Handle (Objekt) des GUI
    h.figure_size = [900 900];       //Aktuelles Grafikobjekt auf 600x600 Pixel Größe festlegen
    h.children.isoview='on';         //Ausdehnungen in x- und y-Richtung gleich
    h.children.margins = [0,0,0,0];  //Keinen Bildrand lassen
    //Koordinaten des oberen linken und unteren rechten Bildpunktes. (?)
    //Entsprechend wird die Darstellung skaliert.
    xmin=-12;
    ymin=-12; 
    xmax=12; 
    ymax=12;
    h.children.data_bounds=[xmin,xmax,ymin,ymax]; 
    h.pixmap = "on"; //Mit einem Puffer für das aktuell gezeichnete Bild arbeiten
endfunction
//Funktion zur Transformation eines Punktes auf einem Körper in das Inertialkoordinatensystem (ebene Transformation).
//Auf dem Körper hat der Punkt die Koordinaten (x_koerper,y_koerper)
//Der Körper selbst hat im Inertialsystem die Koordinaten x,y und ist im phi verdreht.
function punkt = berechnePunkt(x_koerper,y_koerper,x,y,phi)
    punkt =  [x;y] + [cos(phi),-sin(phi);sin(phi),cos(phi)]*[x_koerper;y_koerper];
endfunction
//Alle Umrißpunkte eines Körpers entsprechend seiner aktuellen Lage bestimmen:
//Hier sind x_koerper,y_koerper Zeilen-Vektoren, die alle x- bzw. y-Koordinaten des Körperumrisses enthalten
function punkte = berechneUmriss(x_koerper,y_koerper,x,y,phi)    
    gr = size(x_koerper);
    spalten = gr(2);
    punkte = zeros(2,gr(2));
    for i=1:spalten
        punkte(:,i) =  berechnePunkt(x_koerper(1,i),y_koerper(1,i),x,y,phi);
    end
endfunction
function animieren(t,x,y,phi,x2,y2,phi2,x3,y3,phi3)
    xe = [0,2,2,0,0]; //Rechteckumriß als Polygon, x-Koordinaten
    ye = [0,0,5,5,0]; //Rechteckumriß als Polygon, y-Koordinaten
    param = 0:0.01:2*%pi;
    xee = cos(param); 
    yee = 2*sin(param); 
    umriss = berechneUmriss(xe,ye,x(1),y(1),phi(1));
    umriss2 = berechneUmriss(xe,ye,x2(1),y2(1),phi2(1));
    umriss3 = berechneUmriss(xee,yee,x3(1),y3(1),phi3(1));
    xfpoly(umriss(1,:),umriss(2,:),1);  //Rechteck in den Puffer zeichnen
    xfpoly(umriss2(1,:),umriss2(2,:),1);  //2. Rechteck in den Puffer zeichnen
    xfpoly(umriss3(1,:),umriss3(2,:),1);  //Ellipse in den Puffer zeichnen
//ACHTUNG STACK-artige Struktur: Das zuletzt hinzugefügte Objekt ist children Nr1.
    a=get("current_axes");         //Wurzelobjekt im Hierarchiebaum der Grafikobjekte holen
    a.children(3).background=5;    //erstes Kindobjekt (das Rechteck) wählen und rot färben
    a.children(2).background=6;    //erstes Kindobjekt (das Rechteck) wählen und rot färben
    a.children(1).background=7;    //erstes Kindobjekt (das Rechteck) wählen und rot färben
    realtimeinit(1);             //Realtimemodus setzen und Animationsgeschwindigkeit festlegen
    gr=size(t);
    zeitschritte = gr(2);
    for index=1:1:zeitschritte     //Schleife, in der die Animationsschritte durchgeführt werden
        realtime(t(index));               //aktuelle Zeit zu aktuellen Ereignissen setzen
        umriss = berechneUmriss(xe,ye,x(index),y(index),phi(index));
        umriss2 = berechneUmriss(xe,ye,x2(index),y2(index),phi2(index));
        umriss3 = berechneUmriss(xee,yee,x3(index),y3(index),phi3(index));
        a.children(3).data = [umriss(1,:)',umriss(2,:)']; //Polygonpunkte in Objekt schreiben
        a.children(2).data = [umriss2(1,:)',umriss2(2,:)']; //Polygonpunkte in Objekt schreiben
        a.children(1).data = [umriss3(1,:)',umriss3(2,:)']; //Polygonpunkte in Objekt schreiben
        draw(a);                        //Gesamte Grafikobjekte in Puffer zeichnen
        show_pixmap();                  //...und darstellen
    end
    h.pixel_drawing_mode='copy';        //Mode: Gesamtes fertiges Bild nach Zeichnen im Puffer anzeigen
endfunction
t=0:0.01:3;
phi=2*%pi*t;
x=t*2;
y=t;
phi2=-1.5*%pi*t;
x2=t*2-3;
y2=t-2;
phi3=-1*%pi*t;
x3=t*2-1;
y3=t-3;
while 1==1
    grafikmodus_initialisieren();
    animieren(t,x,y,phi,x2,y2,phi2,x3,y3,phi3);
    xclick(); //Zum Wiederholen in's Bild klicken
end

Code 7.2-3: 003_animation_mehrkoerper.sce - Scilab-Animations-Skript.