Farben


... [ Seminar "Einführung in Haskell" ] ... [ Inhaltsverzeichnis ] ... [ zurück ] ... [ weiter ] ...

Farben


Einleitung

Farben werden durch Quadrupel von real Werten aus dem Bereich [0..1] dargestellt. Die ersten drei Werte stehen für blau, grün und rot. Der vierte Wert steht für Transparenz ("alpha").

type ColorE = ( FractionE, FractionE, FractionE, FractionE )

Die Farbwerte sind bereits mit der Transparenz multipliziert, und sind denentsprechend kleiner gleich alpha. Durch diese Bedingung kann Unsichtbarkeit definiert werden:

unsichtbar = (0, 0, 0, 0)

Hiermit können alle Farben definiert werden, z.B.

rot
=
(0, 0, 1, 1)
grün
=
(0, 1, 0, 1)
schwarz
=
(0, 0, 0, 1)
weiss
=
(1, 1, 1, 1)

Interpolation

Um weiche Übergänge im Raum zu erzeugen, bietet es sich an zwischen Farben zu interpolieren. Hierzu wird die Funktion lerpC verwendet:

lerpC :: FractionE → ColorE → ColorE → ColorE
lerpC w (b1, g1, r1, a1) (b2, g2, r2, a2) = (h b1 b2, h g1 g2, h r1 r2, h a1 a2)
    where
h x1 x2 = w * x1 + (1 - w) * x2

Der Wert w gibt dabei das Gewicht der ersten Farbe innerhalb der neuen Farbe an.

Beispiele für Interpolation:
Das zweite Beispiel beruht auf der vierfachen Anwendung von lerpC.

zweiFarben :: ColorE → ColorE → ImageC
zweiFarben f1 f2 =  \ (x,y) →
lerpC y f1 f2

bilerpC :: ColorE → ColorE → ColorE → ColorE → ImageC
bilerpC lo ro lu ru = \ (x,y) →
lerpC y (lerpC x lu ru) (lerpC x lo ro)

Bild zwei Farben
Bild bilerpC
Grafische Darstellung zweiFarben
Grafische Darstellung bilerpC


Überlagerung

Eine ähnliche Operation wie die Interpolation ist die Überlagerung von Farben, welche zur Überlagerung von Bildern benötigt wird. Das Ergebnis ist eine Blende der zwei Farben, abhängig von der Durchlässigkeit der ersten Farbe.

overC :: ColorE → ColorE → ColorE
(b1, g1, r1, a1) `ocerC` (b2, g2, r2, a2) = (h b1 b2, h g1 g2, h r1 r2, h a1 a2)
   where
h x1 x2 = x1 + (1- a1) * x2

Liften

Viele Operationen auf Bildern resultieren aus Änderungen der Punkte. So kann z.B. die Überlangerung zweier Bilder mit Hilfe von overC definiert werden:
over :: ImageC → ImageC → ImageC
(top ‘over ‘ bot) p = top p ‘overC‘ bot p

Für dieses allgemeine Muster lassen sich folgende Funktionen ableiten:

lift1 :: (α → β) → (p → α) → (p → β)
lift2 :: (α → β → γ) → (p → α) → (p → β) → (p → γ)
lift3 :: (α → β → γ → δ) → (p → α) → (p → β) → (p → γ) → (p → δ)

lift1 h f1 p         = h (f1 p)
lift2 h f1 f2 p     = h (f1 p) (f2 p)
lift3 h f1 f2 f3 p = h (f1 p) (f2 p) (f3 p)

Hierbei kann p als Punkt und p → α = Image α betrachtet werden. Allerdings sind alle lift-Funktionen polymorph gegenüber dem Bereichstyp(hier: Punkt) und können daher für alle Typen verwendet werden.
Das "nullfache Liften" bedeutet keine Veränderung des Bildes. Es ist konstant und somit bereits durch Haskells const funktion definiert:

const :: α → (p → α)
const a p          = a

Mit Hilfe der const Funktion können einfarbige Bilder erzeugt werden, z.B.:

empty
=
const invisible
whiteI 
=
const white
blackI
=
const black

Nun lässt sich over einfacher darstellen:

over = lift2 overC

Zusätzlich können mit den Liftfunktionen Selektion und Bildinterpolation definiert werden.

Selektion
cond :: Image Bool → Image α → Image α → Image α
cond = lift3 (λ a b c → if a then b else c)
(In Pan entsprechend mit einem überladenen if-Operator implementiert: cond = lift3 ifE)

Bildinterpolation
lerpI :: Image Frac → ImageC → ImageC → ImageC
lerpI = lift3 lerpC

Beispiel: Mehrere überlagerte Schachfelder

ueberlagertesSchach :: ImageC
ueberlagertesSchach =  lerpI wavDist1 (bwIm schach) (ybIm (polarSchach 10))

Bild überlagerte Schachfelder
   Grafische Darstellung ueberlagertesSchach




... [ Seminar "Einführung in Haskell" ] ... [ Inhaltsverzeichnis ] ... [ zurück ] ... [ weiter ] ... [ nach oben ] ...