|
Prof.
Urban
|
![]() |
![]() |
||
Wir wollen drei farbige Bälle (Kreisscheiben) darstellen. Das zugehörige Programm könnte so aussehen
// Drei bunte Bälle bewegen sich
Ball ball1, ball2, ball3;
void setup() {
size(200,200);
ball1 = new Ball(#ff0000); // roter Ball
ball2 = new Ball(#00ff00); // grüner Ball
ball3 = new Ball(#0000ff); // blauer Ball
frameRate(30);
smooth();
}
void draw() {
background(0);
ball1.move(); ball2.move(); ball3.move();
ball1.paint(); ball2.paint(); ball3.paint();
}
////////////////////////////////////////////////////////////
//
class Ball {
float x,y; // Ort
float vx,vy; // Geschwindigkeit
float r; // Radius
int col; // Farbe
Ball(int farbe) {
r = 20;
col = farbe;
x = random(2*r,width-2*r);
y = random(2*r,height-2*r);
vx = random(-4,4);
vy = random(-4,4);
paint();
}
// das Ballobjekt darstellen
void paint() {
fill(col);
noStroke();
ellipseMode(RADIUS);
ellipse(x,y,r,r);
}
// den Ball bewegen
void move() {
// jeder Aufruf aktualisiert die Koordinaten (x/y)
// sowie den Geschwindigkeitsvektor (vx/vy)
}
}
//
////////////////////////////////////////////////////////////
Um die Bälle zu bewegen, müssen wir ihre Mittelpunktskoordinaten x / y in der Methode move() immer wieder verändern. Eine gleichförmige Bewegung erhalten wir, indem wir in jedem Schritt den Vektor vx / vy addieren. (in den folgenden Beispielen wollen wir diesen Geschwindigkeitsvektor immer unverändert lassen). Das ist ganz einfach, da x und y Attribute der Klasse Ball sind.
// den Ball bewegen
void move() {
x = x+vx;
y = y+vy;
}
Allerdings hat diese Methode einen kleinen Nachteil: nach kurzer Zeit verlassen die Bälle den sichtbaren Fensterbereich und bleiben für immer verschwunden.
Gerät der Mittelpunkt des Balls aus dem sichtbaren Bereich, wird er zum gegenüberliegenden Fensterrand verschoben. Dadurch scheint ein Ball, der links aus dem Fenster läuft, von rechts wiederzukommen. Wir ergänzen die obige Methode um die notwendigen Verschiebungen in den vier Himmelsrichtungen.
// den Ball bewegen
void move() {
x += vx;
y += vy;
if (x<0) x += width;
if (x>=width) x -= width;
if (y<0) y += height;
if (y>=height) y -= height;
}
Auffällig: die Bälle 'springen' ans andere Ende, was einen etwas unruhigen Eindruck hinterlässt.
Wir bemerkten diesen Sprung gar nicht, wenn der springende Ball vorübergehend unsichtbar wäre, weil er das Fenster verlassen hat. Probieren wir Folgendes: Erst wenn der Ball das Fenster ganz verlassen hat, wird sein Ort ans gegenüberliegende Fensterende verschoben, und auch wieder so, dass der Ball gerade noch nicht sichtbar ist. Technisch gesehen umgeben wir das Anzeigefenster mit einem Rand, der so breit ist wie ein Kugeldurchmesser (bzw. der Durchmesserr der größten vorhandenen Kugel). Der Ball wird verschoben, wenn sein Mittelpunkt um mehr als r nach draußen gewandert ist
// den Ball bewegen
void move() {
x += vx;
y += vy;
if (x<0-r) x += width+2*r;
if (x>=width+r) x -= width+2*r;
if (y<0-r) y += height+2*r;
if (y>=height+r) y -= height+2*r;
}
This browser does not have a Java Plug-in.
Get the latest Java Plug-in here.
Wie machen Mathematiker aus einem Quadrat eine unendlich große Fläche? Sie denken sich die rechte Seite des Fensters mit der linken verklebt (das ergibt eine zylindrische Röhre). Ein nach links davonwandernder Ball kommt dann von rechts wieder, für kurze Zeit ist ein Teil von ihm (noch) links und der dort unsichtbare Teil (bereits) rechts zu sehen. Im zweiten Schritt verkleben sie den oberen und den unteren Rand. Umgekehrt: Wir stellen die Vorgänge auf einem Torus dar, indem wir ihn aufschneiden und flach auflegen.
Wie lösen wir das Problem mit dem 'zerteilten Ball'? Am einfachsten erzeugen wir falls nötig, einen zweiten Ball im passenden Abstand. Java clippt die Grafikobjekte automatisch ins Anzeigefenster. Genauere Überlegung zeigt: bei waagrechtem Verlassen brauchen wir 2 Bälle horizontal verschoben, senkrecht 2 Bälle vertikal verschoben. In den Ecken wird der Ball jedoch in 4 Teile zerteilt! Diese Vervielfachung soll die paint()-Methode erledingen.
// das Ballobjekt darstellen
void paint() {
fill(col);
noStroke();
ellipse(x,y,r,r);
// falls der Ball nicht über den Rand reicht, zurück
if (x>=r && x<width-r && y>r && y<height-r) return;
if (x<r) ellipse(x+width,y,r,r); // Ball links hinaus
if (y<r) ellipse(x,y+height,r,r); // Ball unten hinaus
if (x<r && y<r) ellipse(x+width,y+height,r,r); // Ball in der Ecke
}
// den Ball bewegen // wir kümmern uns nicht um den rechten und unteren Randbereich, // dieser wird wenn nötig von paint() hinzugefügt
void move() {
x += vx;
y += vy;
if (x<0-r) x += width;
if (x>=width-r) x -= width;
if (y<0-r) y += height;
if (y>=height-r) y -= height;
}
This browser does not have a Java Plug-in.
Get the latest Java Plug-in here.
Würden wir die beschriebene Verklebung tatsächlich durchführen, wäre jedes Objekt genau ein Mal unzerschnitten und vollständig zu sehen.
Wir könnten wieder den netten Trick mit dem Hinterlassen einer Spur anwenden
This browser does not have a Java Plug-in.
Get the latest Java Plug-in here.
Eine zufällige Variation der Ballgröße könnte mehr Abwechslung bringen!
This browser does not have a Java Plug-in.
Get the latest Java Plug-in here.
Mithilfe eines Arrays von Bällen sollen 50 Bälle umherfliegen, die unterschiedliche Farben besitzen (HSB Modell). Spiele Dich mit der Transparenz dieser Bälle.
100 weiße Bälle auf schwarzem Hintergrund. Je größer ein Ball ist (überlege eine sinnvolle Maximalgröße), desto durchsichtiger soll er sein.