Victor Vasarely
Seite zum Projekt Vasarely des IF-EF im Schuljahr 2024/25
Im Projekt Kunst mit Processing hast Du schon den Maler Victor Vasarely kennengelernt.
Vasarely (1906-1997) war ein französischer Maler und Grafiker ungarischer Abstammung. Er zählt zu den Mitbegründern der künstlerischen Richtung Op-Art
Du sollst nun erneut ein Bild im Stile von Vasarely mit Processing erstellen. Diesmal aber mit den Techniken der Objektorientierten Programmierung. Dabei sollst Du alle bisher gelernten Konzepte im Projekt verwenden:
- Klassen und Objekte
- Variablen und Attribute
- Methoden mit Rückgaben und / oder Parametern
- Schleifen (kopfgesteuerte und Zählschleifen)
- Bedingte Anweisungen
Du findest Hilfen in den bekannten Lernpfaden und in dieser Taskcard.
Eine Musterlösung des vollständigen Projektes findest Du hier:
Erstelle ein neues Processing-Projekt und speichere es unter einem sinnvollen Namen ab. Erstelle schonmal eine setup() und draw() Methode, die die Zeichenfläche vorbereiten.
🔎 Lösung
void setup() {
// (optionale) Colormode ändern, um "schönere" Zufallsfarben zu erstellen
colorMode(HSB, 360, 100, 100);
// Größe der Leinwand festlegen
size(800, 800);
// Hintergrundfarbe
background(120);
}
void draw() {
// Erstmal leer
}
Das folgende Klassendiagramm soll dem Projekt zugrunde liegen:
classDiagram
Form <-- Kachel : form
class Kachel {
-x: int
-y: int
-farbe: color
+Kachel(pX: int pY: int)
+getX() int
+getY() int
+getFarbe() color
+getForm() Form
+draw()
}
class Form {
+art: String
+farbe: color
+Form(pFarbe: color)
+getArt() String
+getFarbe() color
+draw(pX: int, pY: int)
}
classDef default fill:#fff,stroke:#333;Analysiere das Klassendiagramm und beantworte folgende Fragen:
- Welche Attribute haben die Klassen jeweils?
- Welche Parameter haben die Konstruktoren der Klassen?
Modellierung
Die Zeichnung besteht aus Kachel Objekte, die in einem zweidimensionalen Array gespeichert werden. Jedes Kachel kennt ein Form Objekt, dass die geometrische Figur darin anzeigt. Beide haben eigene Farben. Eine Form besitzt eine art die als Text-String gespeichert wird. Diese kann einer von "ellipse", "kreis", "quadrat", "raute", "dreieck" oder "pyramide" sein. Jede Art zeichnet eine andere Figur auf den Hintergrund. Der Typ wird beim Erstellen des Objektes zufällig gewählt.
Kachel wählt im Konstruktor eine zufällige Farbe für den Hintergrund und die enthaltene Form.
Die Form wird dann im Konstruktor mit der Zufallsfarbe erstellt und im Attribut form gespeichert.
Damit das Symbol an der passenden Stelle gezeichnet werden kann, bekommt die draw()-Methode von Form die x und y Koordinaten des Zentrums des Quadrats als Parameter übergeben. Die draw() Methode von Form wird innerhalb der draw() Methode von Kachel aufgerufen. Diese wiederum werden durch passende Schleifen innerhalb der Hauptmethode draw() aufgerufen.
flowchart TD
classDef start,stopp fill:#bfffbe,stroke:#4bdc6e,stroke-width:2px,font-weight:600;
classDef befehl fill:#b2dfff,stroke:#0096ff,stroke-width:2px,font-weight:600;
classDef aufruf fill:#fbe49e,stroke:#f1b400,stroke-width:2px,font-weight:600;
classDef verzweigung fill:#ffdcd8,stroke:#cd362c,stroke-width:2px,font-weight:600;
classDef notiz fill:#f3f3f3,stroke:#a99f96,color:#a99f96,stroke-width:1px,stroke-dasharray: 5 5,font-style:italic;
subgraph "Form.draw(x, y)"
s2start(Start):::start --> s2p1["fill(farbe)"] --> s2v1{art == "raute"} -- true --> s2p2["quad( ... )"] --> s2stop(Stopp):::stopp
s2v1 -- false --> s2v2{art == "kreis"} -- true --> s2p3["circle( ... )"] --> s2stop
s2v2 -- false --> s2p4@{ shape: text, label: "..." } --> s2stop
class s2p1,s2p2,s2p3 befehl
class s2v1,s2v2 verzweigung
end
subgraph "Kachel.draw()"
start(Start):::start --> p1["fill(farbe)"] --> p2["rect(x, y, 100, 100)"] --> p3[["form.draw(x + 50, y + 50)"]] --> stop(Stopp):::stopp
class p1,p2 befehl
class p3 aufruf
class n1 notiz
end
Grundgerüst implementieren
Implementiere die Klasse Form.
Erstelle zunächst das Grundgerüst der Klasse mit Attributen, Gettern und Konstruktor. Implementiere dann eine einfache Version von draw(), die jede Form als Kreis zeichnet und die art zunächst ignoriert.
🔎 Lösung: Grundgerüst
class Form {
private String type;
private color farbe;
public Form( color pFarbe ) {
type = "circle";
farbe = pFarbe;
}
public String getType() {
return type;
}
public color getFarbe() {
return farbe;
}
public void draw( int pX, int pY ) {
}
}
🔎 Lösung: draw-Methode
public void draw( int pX, int pY ) {
noStroke();
fill(farbe);
circle(pX, pY, 70);
}
Implementiere die Klasse Kachel.
Erstelle auch hier zunächst das Grundgerüst der Klasse mit Attributen, Gettern und Konstruktor. Ignoriere zunächst die Form, aber erstelle eine zufällige Farbe für das Quadrat.
Implementiere dann eine einfache Version von draw(), die das Quadrat im Hintergrund an die passenden Koordinaten zeichnet.
🔎 Lösung: Grundgerüst
class Kachel {
private int x;
private int y;
private color farbe;
private Form form;
public Kachel(int pX, int pY) {
x = pX;
y = pY;
farbe = color(random(0,360),random(40,60),random(60, 90));
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public color getFarbe() {
return farbe;
}
public void draw() {
}
}
🔎 Lösung: draw-Methode
public void draw() {
noStroke();
fill(farbe);
square(x, y, 100);
}
Erstelle in der draw() Methode im Hauptprogramm Form und Kachel Objekte und rufe deren draw() Methoden auf. Variiere die Parameter und prüfe, ob alles wie erwartet funktioniert.
🔎 Lösung
public void draw() {
// Erstelle eine rote form
Form f = new Form(color(255, 0, 0));
// Zeichen bei (150, 150)
f.draw(150, 150);
// Erstelle eine Kachel bei (50, 50)
Kachel k = new Kachel(50, 50);
k.draw();
}
Die Referenz von Kachel zu Form
Bisher sind Kachel und Form noch getrennt. Jede Kachel soll aber im Konstruktor eine neue Form erstellen und diese in ihrem eigenen Zentrum zeichnen.
- Falls noch nicht passiert, erstelle ein Attribut
formvom DatentypFormin der KlasseKachel. - Erstelle im Konstruktor von
Kachelein neues Objekt der Klasse Form. - Rufe in
Kachel.draw()diedraw()Methode vonFormauf.
Teste Dein Programm.
🔎 Lösung: Attribut und Konstruktor
class Kachel {
private int x;
private int y;
private color farbe;
private Form form;
public Kachel(int pX, int pY) {
x = pX;
y = pY;
farbe = color(random(0,360),random(40,60),random(60, 90));
form = new Form(color(random(0,360),random(80,100),random(90,100)));
}
// Rest der KLasse ...
}
🔎 Lösung: draw-Methode
public void draw() {
noStroke();
fill(farbe);
square(x, y, 100);
form.draw(x + 50, y + 50);
}
Arrays benutzen
- Implementiere im Hauptprogramm die Instanziierung der
KachelObjekte in einem zweidimensionalen Array mit Hilfe einer Zählschleife. - Implementiere das Zeichnen des Bildes in der
draw()Methode mit einer Zählschleife.
💡 Zweidimensionale Arrays
Ein zweidimensionales Kachel-Array der Größe 8x8 wird so erstellt:
Kachel[][] zwei_dimensionen = new Kachel[8][8];
zwei_dimensionen[0][0] = new Kachel(0, 0);
zwei_dimensionen[1][0] = new Kachel(100, 0);
zwei_dimensionen[0][1] = new Kachel(200, 0);
// ...
Finalisieren
Stelle das Projekt fertig:
- Wähle die Art der Form zufällig (im Konstruktor von
Form). - Prüfe in
Form.draw(), welche Art gezeichnet werden soll und setze diese um.
Eine Musterlösung des vollständigen Projektes findest Du hier: