HSL-Farbraum: Wie ist der kürzeste Weg von einer Farbe zur anderen?
Hallo,
angenommen, ich habe zwei Farben (Farb-Tupel) C1 = (H1, S1, L1) und C2 = (H2, S2, L2), wobei H jeweils von 0° bis 360° geht (zyklisch) und S/L von 0 bis 1. Jetzt möchte ich N 'Zwischenfarben' auf der kürzesten Strecke von C1 nach C2 erstellen. Wie gehe ich da am besten vor? Das Problem habe ich mal grafisch dargestellt.
Bisher war mein Ansatz eine Lineare Interpolation einzelner Komponenten H, S und L. Die ist nicht unbedingt das Wahre bzw. nicht das was ich gesucht habe, da sie z.B, um von (0°, 1, 0.5) -> (45°, 1, 0.5) einfach H zwischen 0° und 45° läuft.
Freue mich über Antworten oder Anregungen.
Cheers
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
![](https://images.gutefrage.net/media/user/scatha/1657905334504_nmmslarge__46_0_232_232_a3b2578f99317112ab5a10511be5a7d3.jpg?v=1657905335000)
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.
![](https://images.gutefrage.net/media/user/Kesselwagen/1580255067767_nmmslarge__1050_655_2060_2060_837dea54bb697cc818f8acbe805f4f52.jpg?v=1580255068000)
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.
![](https://images.gutefrage.net/media/user/rhavin/1447244186566_nmmslarge__2_2_531_531_c22905e846ea2ffed567961f72a77feb.jpg?v=1447244187000)
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.
![](https://images.gutefrage.net/media/user/scatha/1657905334504_nmmslarge__46_0_232_232_a3b2578f99317112ab5a10511be5a7d3.jpg?v=1657905335000)
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.
![](https://images.gutefrage.net/media/user/Kesselwagen/1580255067767_nmmslarge__1050_655_2060_2060_837dea54bb697cc818f8acbe805f4f52.jpg?v=1580255068000)
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
![](https://images.gutefrage.net/media/user/scatha/1657905334504_nmmslarge__46_0_232_232_a3b2578f99317112ab5a10511be5a7d3.jpg?v=1657905335000)
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.
![](https://images.gutefrage.net/media/user/rhavin/1447244186566_nmmslarge__2_2_531_531_c22905e846ea2ffed567961f72a77feb.jpg?v=1447244187000)
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.
![](https://images.gutefrage.net/media/user/Kesselwagen/1580255067767_nmmslarge__1050_655_2060_2060_837dea54bb697cc818f8acbe805f4f52.jpg?v=1580255068000)
@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
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 :)