Bildbearbeitung und Rendering - Cinderella Dokumentation
Description: The user's guide to the Interactive Geometry Software Cinderella

Zum Inhalt

# Bildbearbeitung und Rendering

Cinderella.2 führt verschiedene Möglichkeiten ein, um mit Bildern in einer geometrischen Konstruktion umzugehen. Einerseits ist es möglich, Bilder in eine Mediendatenbank zu laden und diese frei innerhalb von CindyScript zu verwenden. Bilder können beliebig verschoben, gedreht, skaliert, perspektivisch transformiert oder sogar durch eine Funktion transformiert werden. Andererseits ist es möglich, die Zeichnungsfunktionen von CindyScript zu verwenden, um benutzerdefinierte Bilder zu erstellen, die wiederum als Vorlage für andere Zwecke verwendet werden.

### Der Media Browser

Vor allen Bilddarstellungen muss ein bestimmtes Bild in eine Cinderella-Konstruktion geladen werden. Dies geschieht über den Media Browser, über den Sie auf alle für eine Konstruktion benötigten Bilder zugreifen können. Der Media Browser wird über das Menüelement Datei/Media Browser geöffnet. Sie können Bilder laden, indem Sie die +-Schaltfläche drücken, und sie wieder entfernen, indem Sie die --Schaltfläche drücken. Sobald ein Bild geladen ist, sehen Sie seinen internen Namen und eine Vorschau des Bildes. Standardmäßig ist der Bildname der ursprüngliche Dateiname, aber Sie können den internen Namen ändern, indem Sie doppelt klicken und ihn bearbeiten. Unter diesem Namen kann auf das Bild innerhalb von CindyScript zugegriffen werden.

Der Media Browser

Die Bilder im Media Browser können auch als Bilder für Punkte und Linien sowie als Hintergrund des Viewports verwendet werden. Diese Funktionalität ist über den Inspector verfügbar.

### Zeichnen und Transformieren von Bildern

#### Ein Bild zeichnen: `drawimage(<pos>,<imagename>)`

Beschreibung: Dieser Operator nimmt ein Bild (aus dem Media Browser) und zeichnet es an einer durch das erste Argument gegebenen Position. Der Bezugspunkt ist standardmäßig die Mitte des Bildes. Dies kann jedoch durch Modifizierer geändert werden. Auch die Skalierung und Positionierung des Bildes kann verändert werden.

Beispiele: Der folgende Code zeichnet das Bild namens `myimage` an der durch den Punkt A gegebenen Position.

    drawimage(A,"myimage"))

Der folgende Code zeigt verschiedene Verwendungen des Befehls `drawimage`. Er erstellt die unten gezeigten Grafiken.

    drawimage(A,"myimage");
    drawimage(B,"myimage",scale->1.5,angle->30°);
    drawimage(C,"myimage",ref->"lb");

Bezugspunkte: Bezugspunkte können mit den Modifizierern `ref`, `refx`, `refy` angegeben werden. Während der Modifizierer `ref` eine zweidimensionale Information erwartet, beziehen sich die letzten beiden auf die beiden Koordinatenrichtungen separat. Die Bezugsinformation kann auf drei verschiedene Arten angegeben werden:

- Absolut zu den Pixelkoordinaten des Originalbildes: Wenn das Bild beispielsweise ursprünglich 400 mal 800 Pixel war, gibt der Modifizierer `ref->[100,200]` die Position in der Mitte des linken unteren Viertels des Bildes an.
- Als relativer Quotient bezüglich der Bilddimensionen: In diesem Fall muss die Position durch einen Prozentwert (angegeben als Zeichenkette) angegeben werden. So würde beispielsweise `ref->["25%", "25%"]` wieder den Bezugspunkt in der Mitte des linken unteren Viertels des Bildes platzieren – aber jetzt unabhängig von den Originalbilddimensionen.
- Symbolisch als ein Paar von Buchstaben: Hier stellen in der x-Richtung die Buchstaben `l`, `c`, `r` links, Mitte und rechts dar. In der y-Richtung stellen die Buchstaben `b`, `c`, `t` unten, Mitte und oben dar. So kann die untere linke Ecke entweder durch `ref->"lb"` oder durch `ref->["l","b"]` angegeben werden.

Alle Positionsinformationen können separat für die horizontale und vertikale Richtung verwendet werden, beispielsweise mit `refx->"l"`, `refx->100` oder `refx->"10%"`. Das folgende Bild zeigt die Positionen einiger Bezugspunkte.

Modifizierer: Die Modifizierer dieser Funktion sind unten aufgelistet.

Modifizierer | Parameter | Wirkung
--- | --- | ---
`alpha` | `0.0 ... 1.0` | Opazität des Bildes
`angle` | `real` | Rotationswinkel um den Bezugspunkt
`rotation` | `real` | gleich wie `angle`
`scale` | `real` | Skalierung
`scale` | `vec` | separate Skalierung in beide Richtungen
`scalex` | `real` | Skalierung in x-Richtung
`scaley` | `real` | Skalierung in y-Richtung
`flipx` | `boolean` | vertikale Spiegelung
`flipy` | `boolean` | horizontale Spiegelung
`ref` | `siehe oben` | xy-Position des Bezugspunkts
`refx` | `siehe oben` | x-Position des Bezugspunkts
`refy` | `siehe oben` | y-Position des Bezugspunkts
`rendering` | `"fast" or "nice"` | Renderingqualität festlegen

#### Ein Bild zeichnen: `drawimage(<pos>,<pos>,<imagename>)`

Beschreibung: Zeichnet eine Kopie eines Bildes, dessen Position und Größe durch zwei Bezugspunkte angegeben werden. Standardmäßig sind diese Bezugspunkte die zwei Ecken der Unterkante. Es ist auch möglich, die Position der Bezugspunkte innerhalb des Bildes anzugeben. Die Syntax zur Angabe eines Bezugspunkts ist dieselbe wie im vorherigen Befehl.

Beispiele: Die einfachste Verwendung des Operators ist in folgendem Beispiel gegeben.

    drawimage(A,B,"myimage"))

Erweiterte Verwendungen finden sich im folgenden Beispiel. Sie generieren das unten gezeigten Bild. Beachten Sie, wie in der dritten Zeile die zwei Bezugspunkte einzeln angegeben werden.

    drawimage(A,B,"MyImage");
    drawimage(C,D,"MyImage",aspect->1);
    drawimage(E,F,"MyImage",flipx->true);
    drawimage(G,H,"MyImage",refx1->"20%",refy1->"50%",ref2->"rt");

Modifizierer:

Modifizierer | Parameter | Wirkung
--- | --- | ---
`alpha` | `0.0 ... 1.0` | Opazität des Bildes
`flipx` | `boolean` | vertikale Spiegelung
`flipy` | `boolean` | horizontale Spiegelung
`aspect` | `real` | Seitenverhältnis angeben
`ref1` | `siehe oben` | xy-Position des ersten Bezugspunkts
`refx1` | `siehe oben` | x-Position des ersten Bezugspunkts
`refy1` | `siehe oben` | y-Position des ersten Bezugspunkts
`ref2` | `siehe oben` | xy-Position des zweiten Bezugspunkts
`refx2` | `siehe oben` | x-Position des zweiten Bezugspunkts
`refy2` | `siehe oben` | y-Position des zweiten Bezugspunkts
`rendering` | `"fast" or "nice"` | Renderingqualität festlegen

Beispiel: Ein erweitertes Beispiel ist unten gegeben. Es ordnet iterativ zwei Punkte (gespeichert in den Variablen `a` und `b`) durch eine Transformationsmatrix zu. In jedem Schritt wird ein entsprechendes Bild gezeichnet. Dieser Code erzeugt eine logarithmische Spirale von Bildern. Ein wichtiges Problem kann entstehen, wenn viele Bilder in einer Konstruktion gezeichnet werden. Man kann zwischen schönem oder schnellem Zeichnen der Bilder wählen. Zu diesem Zweck gibt es einen Modifizierer `rendering`, der entweder auf `"nice"` oder auf `fast` gesetzt werden kann. Standardmäßig ist er auf bevorzugte schöne Rendering eingestellt.

    a=(1,0);
    b=(2,-1);
    w=30°;
    m=((cos(w),-sin(w)),
       (sin(w),cos(w)))*0.9;

    repeat(100,
     drawimage(a,b,"MyImage");
     a=m*a;
     b=m*b;
    );

#### Ein Bild zeichnen: `drawimage(<pos>,<pos>,<pos>,<imagename>)`

Beschreibung: Dieser Operator ähnelt dem letzten. Jetzt werden drei Bezugspunkte angegeben, um eine affine Transformation des Bildes zu definieren. Standardmäßig werden die Bezugspunkte auf die Ecken unten/links, unten/rechts und oben/links des Bildes gesetzt. Auch hier kann die Position der Bezugspunkte durch Modifizierer verändert werden.

Beispiel: Die einfachste Verwendung dieses Befehls ist gegeben durch den folgenden Code.

    drawimage(A,B,C,"MyImage"))

Dieser Operator eignet sich sehr gut zum Zeichnen von Bildern unter geometrischen Transformationen wie Spiegelungen oder Rotationen. Dazu muss das Bild in Bezug auf die zugeordneten Bezugspunkte gezeichnet werden. Ein Beispiel dieser Technik ist im Code unten gegeben

    drawimage(A,B,C,"MyImage"))
    drawimage(A',B',C',"MyImage"))

Modifizierer: Der Befehl unterstützt die gleichen Modifizierer wie der vorherige und die folgenden zusätzlichen.

| Modifizierer | Parameter | Wirkung | | --- | --- | --- | | `ref3` | `siehe oben` | xy-Position des dritten Bezugspunkts | | `refx3` | `siehe oben` | x-Position des dritten Bezugspunkts | | `refy3` | `siehe oben` | y-Position des dritten Bezugspunkts |

#### Ein Bild zeichnen: `drawimage(<pos>,<pos>,<pos>,<pos>,<imagename>)`

Beschreibung: Wiederum ist dieser Befehl allgemeiner als der vorherige. Dieses Mal werden die vier Ecken (oder allgemeiner Bezugspunkte) verwendet, um eine projektive Transformation des Bildes anzugeben. Standardmäßig sind die Positionen der Bezugspunkte die Ecken des Bildes, die gegen den Uhrzeigersinn angeordnet sind, beginnend mit links/unten.

Beispiel: Die einfachste Verwendung ist gegeben durch den folgenden Code.

    drawimage(A,B,D,C,"myimage")

Das folgende Bild zeigt das Ergebnis dieser Aussage. Zur Verdeutlichung wurde ein projektives Gitter zum Bild hinzugefügt.

Modifizierer: Der Befehl unterstützt die gleichen Modifizierer wie der vorherige und die folgenden zusätzlichen.

Modifizierer | Parameter | Wirkung
--- | --- | ---
`ref4` | `siehe oben` | xy-Position des vierten Bezugspunkts
`refx4` | `siehe oben` | x-Position des vierten Bezugspunkts

Eine Diät für Ritter Rost

| `refy4` | `siehe oben` | y-Position des vierten Bezugspunkts |

#### Ein Bild verformen: `mapimage(<imagename>,<function>)`

Beschreibung: Dieser Befehl ist äußerst leistungsstark zum Verformen von Bildern durch Funktionen. Normalerweise wird angenommen, dass die Funktion eine Funktion ist, die einen zweidimensionalen Vektor auf einen zweidimensionalen Vektor abbildet. Durch Verwendung des Modifizierers `complex->true` ist es auch möglich, Funktionen zu verwenden, die die komplexe Ebene auf die komplexe Ebene abbilden. Der Bereich der Funktion muss durch die Modifizierer `xrange` und `yrange` angegeben werden. Falls nicht angegeben, werden die Bereiche zwischen 0.0 und 1.0 angenommen. Die durch diese Bereiche definierten Rechtecke werden mit der rechteckigen Region des Bildes identifiziert. Von dort aus werden alle Bildpunkte zugeordnet, um das resultierende Bild zu erstellen. Die Funktionalität ist im Wesentlichen ähnlich dem Befehl `mapgrid`.

Beispiel: Hier wird die x-Achse des Bildes mithilfe einer Funktion verformt, die seine Breite durch Hinzufügen einer sin-Funktion ändert. Im Code wird die Funktion zuerst angegeben. Dann wird sie im Befehl `mapimage` verwendet. Zur besseren Referenz wurde dem Bild ein Gitter hinzugefügt, das die Verformung veranschaulicht.

    f(z):=(z_1*(sin(z_2)+1.3),z_2);
    mapimage("MyImage",f(#),
    xrange->(-1,1),
    yrange->(0,pi),resolution->30
    );
    mapgrid(f(#),color->(0,0,0),alpha->0.3,
    xrange->(-1,1),
    yrange->(0,pi),resolution->30
    );

Dieses Beispiel ähnelt dem vorherigen, verwendet aber jetzt eine komplexe Funktion, um die Zuordnung anzugeben.

    r=complex(A);
    f(x):=exp(r*x);
    mapimage("myimage",f(#),
      complex->true,
      xrange->(0,1),
      yrange->(0,pi),resolution->30
    );

    mapgrid(f(#),complex->true,
    xrange->(0,1),yrange->(0,pi),color->(0,0,0),alpha->0.5
    ,resolutiony->30,resolutionx->10,step->10,size->1);

Modifizierer: Die Funktion unterstützt die folgenden Modifizierer.

Eine Diät für Ritter Rost

Modifizierer | Parameter | Wirkung
--- | --- | ---
`alpha` | `0.0 ... 1.0` | Opazität des Bildes
`xrange` | `vec` | Start und Ende in x-Richtung

| `yrange` | `vec` | Start und Ende in y-Richtung | | `complex` | `boolean` | eine komplexe Funktion verwenden | | `resolution` | `int` | Qualität des resultierenden Bildes |

#### Abrufen der Bilddimensionen: `imagesize(<imagename>)`

Beschreibung: Gibt die Originalgröße eines Bildes zurück. Dies ist ein Paar von Ganzzahlwerten, die sich auf die Pixelbreite und -höhe des Originalbildes beziehen.

#### Abrufen von Pixeldaten: `imagergb(<imagename>,<int>,<int>)`

Beschreibung: Die Funktion `imagergb(<imagename>,x,y)` liefert die Rohdaten der Farbinformation des Pixels an der ursprünglichen Position (x,y). Der Operator gibt einen vierdimensionalen Vektor mit den Rohdaten der Farbe zurück. Die ersten drei Einträge repräsentieren den rgb-Wert, wobei jeder Eintrag von 0 bis 255 reicht. Der letzte Eintrag repräsentiert den Alpha-Wert.

Beispiel: Das folgende (etwas aufwendigere) Codefragment fragt zuerst nach den Dimensionen eines Bildes ab und sampelt dann das Bild in beide Richtungen. Es zeichnet einen Punkt mit der entsprechenden Farbe und Opazität und erstellt dadurch eine sehr grobe Kopie des Bildes.

    drawimage(A,"MyImage",scale->2);
    dim=imagesize("MyImage");
    forall((0..dim_1/10)*10,i,err(i);
      forall((0..dim_2/10)*10,j,
        col=imagergb("MyImage",i,j);
        draw((i,-j)*.03,color->(col_1,col_2,col_3)/255,
                        alpha->col_4,
                        border->false)
      )
    )

### Erstellen von benutzerdefinierten Bildern

Bisher bezogen sich alle Bildoperationen auf Bilder, die über den Media Browser vorgeladen wurden. Es gibt auch die Möglichkeit, Bilder innerhalb von Cinderella zu erstellen. Sobald diese Bilder erstellt sind, können alle Zeichnungsvorgänge von CindyScript mit den `canvas`-Befehlen auf solche Bilder weitergeleitet werden. Das Ergebnis der Zeichnungsvorgänge ist nicht mehr direkt sichtbar. Sobald das benutzerdefinierte Bild jedoch mit Inhalten gefüllt ist, können Sie es verwenden und mit einer der `drawimage`-Operationen zeichnen. Die `canvas`-Operationen sind nach Analogie zu den `drawimage`-Operationen strukturiert. Sie verwenden sie, um die Canvas (das benutzerdefinierte Bild) an einer beliebigen Stelle der Ebene zu platzieren, sogar unter Verwendung von Transformationen. Dieses Konzept ist äußerst leistungsstark und wird in diesem Handbuch nur in seiner grundlegenden Verwendung skizziert.

#### Erstellen eines benutzerdefinierten Bildes: `createimage(<imagename>,<int>,<int>)`

Beschreibung: Der Operator `createimage(<imagename>,width,height)` erstellt einen Bildpuffer der angegebenen Dimensionen. Anfangs ist solch ein Bild vollständig transparent und enthält keine Zeichnungen. Der Bildpuffer ist unter dem angegebenen Namen im Media Browser zugänglich und kann von da an von `drawimage(...)`-Operationen verwendet werden.

#### Löschen eines Bildes: `clearimage(<imagename>)`

Beschreibung: Dieser Operator entfernt alle Inhalte aus einem Bild. Nach Verwendung dieses Operators existiert das Bild immer noch, enthält aber keine Zeichnungen mehr. Es ist vollständig transparent.

#### Entfernen eines Bildes: `removeimage(<imagename>)`

Beschreibung: Dieser Operator entfernt das Bild aus dem Media Browser. Danach kann auf das Bild nicht mehr zugegriffen werden.

### Malen auf einer Canvas

Bilder, die durch ein Skript erstellt werden, können als Canvas verwendet werden, auf die Zeichnungsbefehle von CindyScript weitergeleitet werden können. Dies ist ein sehr mächtiges Konzept, erfordert aber eine kleine Erklärung.

Stellen Sie sich vor, Sie haben ein Codefragment, das eine Zeichnung erstellt, sagen wir:

     linesize(3);
     repeat(10,i,
       drawcircle(K,i*.5);
     );
     drawtext(K+(-2,2),"These are",size->20,color->(1,1,0));
     drawtext(K+(-2,-2),"some circles",size->20,color->(1,1,0));

Diese Zeichnung sieht wie das Bild unten links aus. Jetzt wollen wir diesen Zeichnungscode verwenden, um eine benutzerdefinierte Bitmap zu generieren. Dazu müssen wir zuerst solch eine Bitmap erstellen.

Dies können wir tun, indem wir ein Bild im Initialisierungsteil des Skripts mit folgendem Code erstellen:

    createimage("image",400,400)

Jetzt geben wir eine Region an, in der diese Bitmap als Canvas verwendet werden soll. In unserem Beispiel tun wir dies, indem wir ein Rechteck mit bestimmten Eckpunkten zeichnen.

Der Code zum Zeichnen auf der Canvas ist als Argument an eine `canvas`-Funktion wie folgt enthalten:

    canvas(F,G,E,"image",
        //....here comes the drawing code....
    )

Die Position der Canvas wird als Parallelogramm angegeben, das durch die Eckpunkte F, G und E erzeugt wird. Das obige Bild rechts zeigt, welcher Teil der ursprünglichen Zeichnung von der Canvas erfasst wird. Eigentlich haben alle Zeichnungsvorgänge innerhalb von `canvas` keine direkt sichtbare Wirkung, daher ist das obige Bild rechts nur zu Illustrationszwecken.

Anschließend kann das Bild an einer beliebigen Stelle mit einem `drawimage(...)`-Befehl gezeichnet werden. Der vollständige resultierende Code kann wie folgt aussehen

    clearimage("image");
    canvas(F,G,E,"image",
     linesize(3);
     repeat(10,i,
       drawcircle(K,i*.5);
     );
     drawtext(K+(-2,2),"These are",size->20,color->(1,1,0));
     drawtext(K+(-2,-2),"some circles",size->20,color->(1,1,0));
    );

    drawimage(A,B,C,D,"image");

Der hier verwendete `drawimage(...)`-Befehl erzeugt eine projektive Transformation der generierten Canvas. Es führt zu dem unten links gezeigten Bild

Beachten Sie, dass das Bild in der Canvas nur eine Bitmap ist. Daher muss es mit geeigneter Auflösung angegeben werden. Wenn in der Initialisierung nur eine 80x80-Bitmap verwendet worden wäre, würde das Ergebnis unten rechts entstehen.

Sobald eine Canvas erstellt ist, kann sie ohne weitere Mühe an verschiedenen Stellen und Ausrichtungen mehrmals verwendet werden. Dies wird durch das folgende Codefragment und das entsprechende Bild veranschaulicht.

    drawimage(A,P,M,O,"image");
    drawimage(B,P,M,Q,"image");
    drawimage(D,R,M,O,"image");
    drawimage(C,R,M,Q,"image");

#### Malen auf einer Canvas mit einem Bezugspunkt: `canvas(<pos>,<imagename>,<drawing code>)`

Beschreibung: Dieser Operator verwendet `<imagename>` als Canvas und positioniert sie in Bezug auf einen Bezugspunkt identisch mit den Regeln des Operators `drawimage(<pos>,<imagename>)`. Alle Zeichnungsanweisungen in `<drawing code>` werden an die Canvas weitergeleitet. Die Positionierungsmodifizierer sind identisch mit denen von `drawimage(<pos>,<imagename>)`.

Modifizierer: Der Befehl hat mehrere Modifizierer.

Modifizierer | Parameter | Wirkung
--- | --- | ---
`angle` | `real` | Rotationswinkel um den Bezugspunkt
`rotation` | `real` | gleich wie `angle`
`scale` | `real` | Skalierung
`scale` | `vec` | separate Skalierung in beide Richtungen
`scalex` | `real` | Skalierung in x-Richtung
`scaley` | `real` | Skalierung in y-Richtung
`flipx` | `boolean` | vertikale Spiegelung
`flipy` | `boolean` | horizontale Spiegelung
`ref` | `siehe oben` | xy-Position des Bezugspunkts
`refx` | `siehe oben` | x-Position des Bezugspunkts
`refy` | `siehe oben` | y-Position des Bezugspunkts

#### Malen auf einer Canvas mit zwei Bezugspunkten: `canvas(<pos>,<pos>,<imagename>,<drawing code>)`

Beschreibung: Dieser Operator verwendet `<imagename>` als Canvas und positioniert sie in Bezug auf zwei Bezugspunkte identisch mit den Regeln des Operators `drawimage(<pos>,<pos>,<imagename>)`. Alle Zeichnungsanweisungen in `<drawing code>` werden an die Canvas weitergeleitet. Die Positionierungsmodifizierer sind identisch mit denen von `drawimage(<pos>,<pos>,<imagename>)`.

Modifizierer: Der Befehl hat mehrere Modifizierer.

Modifizierer | Parameter | Wirkung
--- | --- | ---
`flipx` | `boolean` | vertikale Spiegelung
`flipy` | `boolean` | horizontale Spiegelung
`aspect` | `real` | Seitenverhältnis angeben
`ref1` | `siehe oben` | xy-Position des ersten Bezugspunkts
`refx1` | `siehe oben` | x-Position des ersten Bezugspunkts
`refy1` | `siehe oben` | y-Position des ersten Bezugspunkts
`ref2` | `siehe oben` | xy-Position des zweiten Bezugspunkts
`refx2` | `siehe oben` | x-Position des zweiten Bezugspunkts
`refy2` | `siehe oben` | y-Position des zweiten Bezugspunkts

#### Malen auf einer Canvas mit drei Bezugspunkten: `canvas(<pos>,<pos>,<pos>,<imagename>,<drawing code>)`

Beschreibung: Ähnlich wie die obige Aussage. Jetzt werden drei Bezugspunkte verwendet. Die Positionierungsmodifizierer sind identisch mit denen von `drawimage(<pos>,<pos>,<pos>,<imagename>)`.

Modifizierer: Der Befehl unterstützt die gleichen Modifizierer wie der vorherige und zusätzlich.

Modifizierer | Parameter | Wirkung
--- | --- | ---
`ref3` | `siehe oben` | xy-Position des dritten Bezugspunkts
`refx3` | `siehe oben` | x-Position des dritten Bezugspunkts
`refy3` | `siehe oben` | y-Position des dritten Bezugspunkts

Diese Seite wurde automatisch mit KI (Claude) übersetzt und wartet noch auf Überprüfung. → Alle KI-übersetzten Seiten