7.2 Erzeugen von Animationen mit Hilfe von Scilab
|
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.