lehrkraefte:snr:informatik:rgbwuerfel-und-sierpinski-farbig

Mit Python Bild-Dateien erzeugen: RGB-Würfel (als ppm) und farbiges Sierpinski-Dreieck (als SVG)

Ziel heute: Die folgenden Grafiken mit Tigerjython erstellen!

ppm-Datei für RGB-Farbwürfel als .txt (Da ich hier im dokuwiki keine SVG-Dateien hochladen konnte.)

und hier als png:

Vorlagen für die Lektion

from gpanel import *
 
makeGPanel(Size(382, 382))
window(-127, 255, -127, 255)
 
# Code zu ergänzen: Male Farbwürfel Pixel für Pixel
 
# auf Schulcomputer funktioniert:
ausgabe = open("C:\\Users\\kleingeschreibenerVorname.kleingeschriebenerNachname\\RGB-farbwuerfel.ppm", "w")
 
# unter Linux (und vermutlich auch macOS) funktioniert z.B. 
# ausgabe = open("RGB-color-cube.ppm", "w")
 
ausgabe.write("P3\n")
ausgabe.write("383 383\n")
ausgabe.write("255\n")
 
# Code zu ergänzen: Speichere weiter oben Farbinformation in Liste und schreibe sie nun hier in die ppm-Datei.
 
ausgabe.close()
 
delay(2000)
dispose()
from gpanel import *
 
def dreieck_4(x1, y1, x2, y2, x3, y3):
    fillTriangle(x1, y1, x2, y2, x3, y3)
 
def dreieck_3(x1, y1, x2, y2, x3, y3):
 
    print("Code zu ergänzen!")  
    # Code zu ergänzen
 
def dreieck_2(x1, y1, x2, y2, x3, y3):
 
    print("Code zu ergänzen!")  
    # Code zu ergänzen
 
def dreieck_1(x1, y1, x2, y2, x3, y3):
 
    print("Code zu ergänzen!")  
    # Code zu ergänzen
 
makeGPanel(Size(255, 222))
window(0, 255, 0, 222)
 
Px, Py = 0, 0
Qx, Qy = 255, 0
Rx, Ry = 128, 222
 
dreieck_4(Px, Py, Qx, Qy, Rx, Ry)
 
delay(2000)
dispose()
from gpanel import *
 
def berechneRGB(x, y):
 
    # Code zu ergaenzen: RGB-Farbwerte zu gegebener Position (x,y)
 
    return int(rot), int(blau), int(gruen)
 
 
makeGPanel(Size(255, 222))
window(0, 255, 0, 222)
 
# Code zu ergaenzen: Male RGB-Farbrechteck
 
#delay(1000)
#setColor("black")
#triangle(0, 0, 255, 0, 128, 222)
 
#delay(1000)
#setColor("white")
#fillTriangle(0, 0, 128, 222, 0, 222)
#fillTriangle(256, 0, 256, 222, 128, 222)
 
delay(2000)
dispose()
<svg height='222' width='255'>
<rect width='100%' height='100%' fill='#ffffff'/>
<polyline points='0, 222 127.5, 222.0 64.0, 111.0 0, 222 ' style='fill:#ff0000'/>
<polyline points='127.5, 222.0 255, 222 191.5, 111.0 127.5, 222.0 ' style='fill:#0000ff'/>
<polyline points='64.0, 111.0 191.5, 111.0 128, 0 64.0, 111.0 ' style='fill:#00ff00'/>
</svg>
from gpanel import *
 
MAX_TIEFE = 3
# Tiefe 12 schafft Inkscape noch mit Mühe, ab 13 weigert es sich
# Tiefe 8 für dokuwiki svg
 
def berechneRGB(x, y):
    # Farbverteilung auf Dreieck nicht ideal, aber gut genug.
    rot = (255 - y) / 255 * (255 - x)
    gruen = (255 - y) / 255 * x
    blau = y
    maximum = max(rot, blau, gruen)
    rot = rot / maximum * 255
    blau = blau / maximum * 255
    gruen = gruen / maximum * 255
 
    return int(rot), int(blau), int(gruen)
 
def sierpinskiDreieck(x1, y1, x2, y2, x3, y3, tiefe):
    if tiefe == MAX_TIEFE:    
 
        # Code zu ergänzen: Auswahl der richtigen Farbe.    
 
        fillTriangle(x1, y1, x2, y2, x3, y3)
 
        # Code zu ergänzen: Ausgabe des Dreiecks in SVG-Datei
 
    else:
        a12 = (x1 + x2) / 2
        b12 = (y1 + y2) / 2
        a13 = (x1 + x3) / 2
        b13 = (y1 + y3) / 2
        a23 = (x2 + x3) / 2
        b23 = (y2 + y3) / 2
 
        sierpinskiDreieck(x1, y1, a12, b12, a13, b13, tiefe + 1)
        sierpinskiDreieck(a12, b12, x2, y2, a23, b23, tiefe + 1)
        sierpinskiDreieck(a13, b13, a23, b23, x3, y3, tiefe + 1)
        # Folgende Zeile auskommentieren, wenn man das gesamte Farbdreieck möchte.
        # sierpinskiDreieck(a12, b12, a23, b23, a13, b13, tiefe + 1)
 
makeGPanel(Size(255, 222))
window(0, 255, 0, 222)
 
Px, Py = 0, 0
Qx, Qy = 255, 0
Rx, Ry = 128, 222
 
# auf Schulcomputern mit Windows funktioniert:
ausgabe = open("C:\\Users\\kleingeschreibenerVorname.kleingeschriebenerNachname\\sierpinski.svg", "w")
 
# Unter Linux (und wohl auch macOS):
# ausgabe = open("sierpinski.svg", "w")
 
ausgabe.write("<svg height='222' width='255'>\n")
ausgabe.write("<rect width='100%' height='100%' fill='#ffffff'/>\n")
 
sierpinskiDreieck(Px, Py, Qx, Qy, Rx, Ry, 0)
 
ausgabe.write("</svg>\n")
ausgabe.close()
 
print("Fertig mit SVG!")
 
delay(2000)
dispose()

Einige Lösungsvorschläge

Farbwürfel, Ausgabe auch als ppm-Datei

Farbwürfel, Ausgabe auch als ppm-Datei

from gpanel import *
 
makeGPanel(Size(382, 382))
window(-127, 255, -127, 255)
 
rgbWert = [[[255, 255, 255] for y in range(256 + 127)] for x in range(256 + 127)]
 
for b in range(0, 256):
    for r in range(0, 256):
        for g in range(0, 256):
            if r == 255 or g == 255 or b == 255:
                farbe = makeColor(r, g, b)
                setColor(farbe)
                x = r - 0.5 * b
                y = g - 0.5 * b
 
                point(x, y)
 
                rgbWert[int(x) + 127][int(y) + 127] = [r, g, b]
 
print("Schreibe ppm-Datei.")
 
ausgabe = open("C:\\Users\\kleingeschreibenerVorname.kleingeschriebenerNachname\\RGB-farbwuerfel.ppm", "w")
# ausgabe = open("RGB-color-cube.ppm", "w")
ausgabe.write("P3\n")
ausgabe.write("383 383\n")
ausgabe.write("255\n")
 
for y in range(255 + 127, -1, -1):
    for x in range(256 + 127):
        ausgabe.write(str(rgbWert[x][y][0]) + " "\
                    + str(rgbWert[x][y][1]) + " "\
                    + str(rgbWert[x][y][2]) + "\n")
 
print("Fertig!")
ausgabe.close()
 
delay(2000)
dispose()

Sierpinski-Dreieck rekursiv

Sierpinski-Dreieck rekursiv

from gpanel import *
 
# Bitte erhöhen, aber nicht viel grösser als 12 gehen.
MAX_TIEFE = 2
pausenZeit = 100
 
def sierpinskiDreieck(x1, y1, x2, y2, x3, y3, tiefe):
    if tiefe == MAX_TIEFE:    
        fillTriangle(x1, y1, x2, y2, x3, y3)
 
        # Damit auch etwas gezeichnet wird, wenn die Dreiecke 
        # "zu klein" sind.
        if MAX_TIEFE > 7:
            point(int(x1), int(y1))
 
        delay(pausenZeit)
    else:
        a12 = (x1 + x2) / 2
        b12 = (y1 + y2) / 2
        a13 = (x1 + x3) / 2
        b13 = (y1 + y3) / 2
        a23 = (x2 + x3) / 2
        b23 = (y2 + y3) / 2
 
        sierpinskiDreieck(x1, y1, a12, b12, a13, b13, tiefe + 1)
        sierpinskiDreieck(a12, b12, x2, y2, a23, b23, tiefe + 1)
        sierpinskiDreieck(a13, b13, a23, b23, x3, y3, tiefe + 1)
 
makeGPanel(Size(255, 222))
window(0, 255, 0, 222)
 
Px, Py = 0, 0
Qx, Qy = 255, 0
Rx, Ry = 128, 222
 
sierpinskiDreieck(Px, Py, Qx, Qy, Rx, Ry, 0)
 
delay(2000)
dispose()

Farbdreieck

Farbdreieck

from gpanel import *
 
def berechneRGB(x, y):
    # Farbverteilung auf Dreieck nicht ideal, aber gut genug.
    rot = (255 - y) / 255 * (255 - x)
    gruen = (255 - y) / 255 * x
    blau = y
 
    maximum = max(rot, blau, gruen)
    rot = rot / maximum * 255
    blau = blau / maximum * 255
    gruen = gruen / maximum * 255
 
    return int(rot), int(blau), int(gruen)
 
 
makeGPanel(Size(255, 222))
window(0, 255, 0, 222)
 
for x in range(256):
    for y in range(222):
        r, g, b = berechneRGB(x, y)
        # print(r, g, b)
        farbe = makeColor(r, g, b)
        setColor(farbe)
        point(x, y)
 
delay(1000)
setColor("black")
triangle(0, 0, 255, 0, 128, 222)
 
delay(1000)
setColor("white")
fillTriangle(0, 0, 128, 222, 0, 222)
fillTriangle(256, 0, 256, 222, 128, 222)
 
delay(5000)
dispose()

Farbiges Sierpinski-Dreieck, Ausgabe auch als SVG-Datei; ACHTUNG, DAS GEHT EINFACHER MIT FORMATIERTER AUSGABE: %02x für hexadezimal mit führenden Nullen und mindestens zweistellig; STATT FUNKTION hexadezimalZweistellig

Farbiges Sierpinski-Dreieck, Ausgabe auch als SVG-Datei; ACHTUNG, DAS GEHT EINFACHER MIT FORMATIERTER AUSGABE: %02x für hexadezimal mit führenden Nullen und mindestens zweistellig; STATT FUNKTION hexadezimalZweistellig

from gpanel import *
 
MAX_TIEFE = 7
# Tiefe 12 schafft Inkscape noch mit Mühe, ab 13 weigert es sich
# Tiefe 8 für dokuwiki svg
 
def berechneRGB(x, y):
    # Farbverteilung auf Dreieck nicht ideal, aber gut genug.
    rot = (255 - y) / 255 * (255 - x)
    gruen = (255 - y) / 255 * x
    blau = y
    maximum = max(rot, blau, gruen)
    rot = rot / maximum * 255
    blau = blau / maximum * 255
    gruen = gruen / maximum * 255
 
    return int(rot), int(blau), int(gruen)
 
def hexadezimalZweistellig(zahl):
    s = hex(zahl)[2:]
    if len(s) < 2:
        s = "0" + s
    return s
 
def sierpinskiDreieck(x1, y1, x2, y2, x3, y3, tiefe):
    if tiefe == MAX_TIEFE:    
        r, g, b = berechneRGB((x1+x2+x3)/3, (y1+y2+y3)/3)
        farbe = makeColor(r, g, b)
        setColor(farbe)
        fillTriangle(x1, y1, x2, y2, x3, y3)
 
        # Damit auch etwas gezeichnet wird, wenn die Dreiecke 
        # "zu klein" sind.
        if MAX_TIEFE > 7:
            point(int(x1), int(y1))
 
        ausgabe.write("<polygon points='"\
            + str(x1) + ", " + str(222-y1) + " "\ 
            + str(x2) + ", " + str(222-y2) + " "\ 
            + str(x3) + ", " + str(222-y3) + " "\ 
            + " ' style='fill:#"\
            + hexadezimalZweistellig(r)
            + hexadezimalZweistellig(g)
            + hexadezimalZweistellig(b)
            + "'/>\n")
    else:
        a12 = (x1 + x2) / 2
        b12 = (y1 + y2) / 2
        a13 = (x1 + x3) / 2
        b13 = (y1 + y3) / 2
        a23 = (x2 + x3) / 2
        b23 = (y2 + y3) / 2
 
        sierpinskiDreieck(x1, y1, a12, b12, a13, b13, tiefe + 1)
        sierpinskiDreieck(a12, b12, x2, y2, a23, b23, tiefe + 1)
        sierpinskiDreieck(a13, b13, a23, b23, x3, y3, tiefe + 1)
        # Folgende Zeile auskommentieren, wenn man das gesamte Farbdreieck möchte.
        # sierpinskiDreieck(a12, b12, a23, b23, a13, b13, tiefe + 1)
 
makeGPanel(Size(255, 222))
window(0, 255, 0, 222)
 
Px, Py = 0, 0
Qx, Qy = 255, 0
Rx, Ry = 128, 222
 
ausgabe = open("C:\\Users\\kleingeschreibenerVorname.kleingeschriebenerNachname\\sierpinski.svg", "w")
 
# ausgabe = open("sierpinski.svg", "w")
# Wenn man auf Dateien in einem anderen Verzeichnis zugreifen will,
# muss man unter Windows den Pfad sinngemaess wie folgt angeben.
# ausgabe = open("C:\\Users\\Vorname.Nachname\\Downloads\\ausgabe.txt", "w")
 
ausgabe.write("<svg height='222' width='255'>\n")
ausgabe.write("<rect width='100%' height='100%' fill='#ffffff'/>\n")
 
sierpinskiDreieck(Px, Py, Qx, Qy, Rx, Ry, 0)
 
ausgabe.write("</svg>\n")
ausgabe.close()
 
print("Fertig mit SVG!")
 
delay(2000)
dispose()

1)
Weiss ist hier und im nächsten Dreieck nicht genau im Schwerpunkt des 2-Simplex, damit relativ komplizierte Umrechnungen nicht zusätzliche Schwierigkeiten bereiten.
  • lehrkraefte/snr/informatik/rgbwuerfel-und-sierpinski-farbig.txt
  • Last modified: 2022/03/27 20:44
  • by Olaf Schnürer