[Java] HSBtoRGB avec teinte proche de zéro

Résolu/Fermé
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 - 27 avril 2012 à 00:01
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 - 27 nov. 2012 à 21:53
Bonjour,

Normalement la méthode Color.HSBtoRGB(float hue, float saturation, float brightness), devrait me renvoyer une couleur rouge lorsque je lui donne une teinte proche de 0. Mais avec certaines valeurs, on me renvoie du noir, ce qui bien sûr ne me convient pas.

Exemple :

System.out.println(new Color(Color.HSBtoRGB(0f, 1f, 1f))); // Color[r=255,g=0,b=0]
System.out.println(new Color(Color.HSBtoRGB(-1e-8f, 1f, 1f))); // Color[r=0,g=0,b=0]

Je pense que le problème est du à une erreur dans le code de l'API Java, donc ce que je cherche ce serait plutôt une astuce pour contourner le problème. Pour l'instant je fais un test pour vérifier que je ne récupère pas du noir, mais ce n'est pas très pertinent dans le cas général, vu que l'on pourrait également avoir du noir si on annule le troisième paramètre...

Les idées sont les bienvenues :-)
A voir également:

1 réponse

bizu53 Messages postés 1274 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 21 juin 2015 859
Modifié par bizu53 le 27/11/2012 à 21:06
(edit:petit déterrage, peut-être plus d'actualité, mais au moins cette question ne reste pas sans réponse)
Mieux qu'une idée : la réponse (ou alors je n'ai pas observé le problème et je demande un autre cas).

System.out.println(Integer.toHexString(Color.HSBtoRGB(-1e-8f, 1f, 1f))); // teinte hors plage [0;1], négative donc ramenée à 0 => couleur attendue : noir   
System.out.println(Integer.toHexString(Color.HSBtoRGB(0, 1f, 1f))); // teinte 0 => couleur attendue : rouge   
System.out.println(Integer.toHexString(Color.HSBtoRGB(1e-8f, 1f, 1f))); // teinte proche de 0 => couleur attendue : rouge   


J'ai bien en sortie :
ff000000   
ffff0000   
ffff0000
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
27 nov. 2012 à 21:15
Alors, ça fait un petit moment que j'ai posé la question, et il me semble que j'avait résolu le problème, je vais fouiller un peu pour voir ce que j'avais fait. Mais la teinte n'est pas hors plage, dans la documentation seuls saturation et brightness doivent être entre 0 et 1, la teinte hue étant censée pouvoir prendre n'importe quelle valeur :

public static int HSBtoRGB(float hue, float saturation, float brightness)
The saturation and brightness components should be floating-point values between zero and one (numbers in the range 0.0-1.0). The hue component can be any floating-point number. The floor of this number is subtracted from it to create a fraction between 0 and 1. This fractional number is then multiplied by 360 to produce the hue angle in the HSB color model.
0
bizu53 Messages postés 1274 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 21 juin 2015 859
Modifié par bizu53 le 27/11/2012 à 21:39
Au temps pour moi, effectivement. J'ai hésité avec une autre cause : celle de la précision des float (mais voyant le nombre négatif j'ai conclu trop hâtivement celle que j'ai mentionnée).

Je viens de confirmer que c'est bien une histoire de précision (avec une boucle for de -0.000_01 à 0.000_01 avec un pas de 0.000_000_01)
En copiant le code de Color.HSBtoRGB pour utiliser des double au lieu de float : là où celle utilisant les float me sort du noir, celle utilisant les double sort bien du rouge.
La variable h est en cause dans l'implémentation de Color.HSBtoRGB.

{  
 final float hue = -1e-8f;  
 final double h = (hue - (float) Math.floor(hue)) * 6.0f;  
 System.out.println(h); // affiche 6.0  
}  
{  
 final double hue = -1e-8f;  
 final double h = (hue - Math.floor(hue)) * 6.0;  
 System.out.println(h); // affiche 5.99999994  
}
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
27 nov. 2012 à 21:53
J'ai retrouvé comment j'avais corrigé le problème, mais c'était une bidouille qui marche pour mon code, et qui n'est probablement pas généralisable pour tout les codes :

J'avait un tableau pour faire une palette de couleurs, pour contourner le problème j'ai rajouté une case à la fin, de manière à ce que 0 et 1 renvoient la même couleur. Ce qui se passe c'est que la fraction des teintes est entre [0-1] alors qu'en général les intervalles sont [0-1[ donc le 1 vaut 0 mais pas là...

Bref, je mets en résolu ;-)
0