HSL-Farbraum: Wie ist der kürzeste Weg von einer Farbe zur anderen?


31.01.2020, 18:59

Zusätzliche Schwierigkeiten:

  • Die Berechnung wird auf einem Mikrocontroller ohne Divisionseinheit und ohne Gleitkommaeinheit ausgeführt, also wenn es geht ohne SIN/COS/SQRT etc.
  • Eine Transformation in RGB ist schwierig, weil es stets mehrere Farbpunkte sind, die von H her k * ∆H auseinander liegen

2 Antworten

Es ist zwar keine Abkürzung, aber mir ist als Idee eine mögliche Alternativstrecke eingefallen, nämlich immer durch die graue Achse zu gehen.
Also als Beispiel, wenn man von (0°, 0.2, 0.5) nach (45°, 0.4, 0.8) wandern möchte,

würde man zuerst von (0°, 0.2, 0.5) nach (0°, 0, 0.65) wandern und danach von
(0°, 0, 0.65) nach (45°, 0.4, 0.8) - beide Male linear interpoliert.

Damit es noch etwas gleichmäßiger aussieht, eventuell vorher eine "Strecken"-berechnung machen, damit die Stufen auf beiden Teilen des Weges gleich groß aussehen.

Streckenlängen = Wurzeln aus (dH² + dS² + dL²)

Somit vermeidet man die in der Praxis etwas beliebig aussehende Wanderung durch den Farbkreis.


Kesselwagen 
Beitragsersteller
 31.01.2020, 17:15

Hey vielen Dank, das ist eine ziemlich coole Idee in der Tat sozusagen die Wanderung durch den Farbkreis zu verstecken :) Ich schaue mal nach wie man das am besten codetechnisch realisiert.

2

HSL/HIQ ist ein Polarkoordinaten-System. Du wandelst in ein 3D-System um (z.B. I/L = Z und XY aus den Polarkoordinaten), berechnest dort die Zwischen-Koordinaten und wandelst sie zurück.


Kesselwagen 
Beitragsersteller
 31.01.2020, 17:17

Stimmt, danke, habe jetzt mal die Punkte ins kartesische System überführt und schaue mir den Gerade dort an und wie es sich am besten auf nem Mikrocontroller umsetzen lässt :)

1
scatha  31.01.2020, 17:31
@Kesselwagen

Ich hätte - wenn es sein mußte - früher - also ~1990 -- Sin/Cos mit einer Tabelle berechnet.
Man braucht ja nur die von Sin 0°-45° (die wären dann wohl als 0x00 bis 0x3F codiert) Der Rest kann gespiegelt werden. Auf Genauigkeit kommt es sowieso nicht an.
Allerdings weiß ich nicht, was die heutigen Geräte können, und ob man solche Sperenzchen noch machen muss.

0
Kesselwagen 
Beitragsersteller
 31.01.2020, 17:41
@scatha

Joa Genauigkeit hier spielt ne ziemlich untergeordnete Rolle. Wenn's auf ne einfache Gleichung hinausläuft mit sin/cos würde ich wie Du ne LUT nehmen oder Fixed Point CORDIC (leider hat der Mikrocontroller keine eigene Gleitkommaeinheit, auch keine Divisionseinheit ^^). Jedoch sieht selbst die einfache Modellierung der Gerade C(t) = C1 + t * (C2 - C1), also Polar -> Kartesisch -> Polar schon ziemlich bekloppt aus: https://www.wolframalpha.com/input/?i=sqrt%28%28a+*+cos%28b%29+%281+%2B+x%29+-+c+*+cos%28d%29%29%5E2+%2B+%28a+*+sin%28b%29+%281+%2B+x%29+-+c+*+sin%28d%29%29%5E2%29

Und den Winkel habe ich noch gar nicht versucht auszurechnen. Also wirds wohl die Doppel-Interpolation :D

1
scatha  31.01.2020, 17:44
@Kesselwagen

Vielleicht kommen ja noch andere Vorschläge :) WolframAlpha meckert wegen "Rechenzeit überschritten" - schade, das hätte ich schon gerne gesehen. Aber vielleicht klappt es morgen früh.

0
rhavin  31.01.2020, 18:30
@Kesselwagen

Ich hab das alles schonmal in C# gemacht, ich such das mal - falls ich dran denke - heute bend raus, wenn ich zuhause bin. Ich meine, das ging mit einigen Vorberechnungen auch ohne sin/cos.

0
Kesselwagen 
Beitragsersteller
 31.01.2020, 18:54
@rhavin

@scatha: Letztendlich läuft die Geradengleichung das neue S (rho) auf sqrt(S1^2 (t + 1)^2 - 2 S1 S2 (t + 1) cos(H1 - H2) + S^2) hinaus - das ist das was WA dafür ausspuckt, ist aber zu kompliziert zum Implementieren ^^

@rhavin: Würde mich sehr freuen - wäre bestimmt eine große Hilfe für mich :) Rein theoretisch hätte ich es auch im RGB Raum (einfach) lösen können, da die Farben zur Darstellung eh wieder zurück ins RGB müssen. Allerdings sind meine Farbpunkte C1 und C2 auch noch von nem Verschiebungsparameter k * ∆H beim H abhängig, also

  • C1 = (H1 + k * ∆H, S1, L1)
  • C2 = (H2 + k * ∆H, S1, L1)

Das macht die Sache nichtlinear fürs RGB Raum. Hmm :/ :D

0