J’ai un tableau de type bitmap 2D de 500 * 500 valeurs, par exemple. J’essaie de créer un dégradé linéaire sur le tableau afin que le bitmap résultant ressemble à ceci (en niveaux de gris): Exemple de dégradé http://soffr.miximages.com/algorithm/gradient_12.jpg
L’entrée serait le tableau à remplir, deux points (comme le sharepoint départ et d’arrivée de l’outil Dégradé de Photoshop / GIMP) et la plage de valeurs à utiliser.
Mon meilleur résultat actuel est le suivant:
texte alt http://img222.imageshack.us/img222/1733/gradientfe3.png
… qui est loin de ce que je voudrais réaliser. Cela ressemble plus à un dégradé radial.
Quel est le moyen le plus simple de créer un tel dégradé? Je vais l’implémenter en C ++, mais j’aimerais un algorithme général.
Dans votre exemple, il semble que vous ayez un dégradé radial. Voici mon explication mathématique impromptue pour les étapes dont vous aurez besoin. Désolé pour le calcul, les autres réponses sont meilleures en termes de mise en œuvre.
| c | | Vect: ____.______________ | |
C’est vraiment une question de maths, donc on peut se demander si elle «appartient» vraiment à Stack Overflow, mais vous devez quand même projeter les coordonnées de chaque sharepoint l’image sur l’axe de votre dégradé et utiliser cette Couleur.
Mathématiquement, ce que je veux dire, c’est:
A = (x2 - x1)
et B = (y2 - y1)
C1 = A * x1 + B * y1
pour le sharepoint départ et C2 = A * x2 + B * y2
pour le point final ( C2
doit être supérieur à C1
) C = A * x + B * y
Si C <= C1
, utilisez la couleur de départ; si C >= C2
, utilisez la couleur de fin; sinon, utilisez une moyenne pondérée:
(start_color * (C2 - C) + end_color * (C - C1))/(C2 - C1)
J'ai fait quelques tests rapides pour vérifier que cela fonctionnait fondamentalement.
Je vais juste poster ma solution.
int ColourAt( int x, int y ) { float imageX = (float)x / (float)BUFFER_WIDTH; float imageY = (float)y / (float)BUFFER_WIDTH; float xS = xStart / (float)BUFFER_WIDTH; float yS = yStart / (float)BUFFER_WIDTH; float xE = xEnd / (float)BUFFER_WIDTH; float yE = yEnd / (float)BUFFER_WIDTH; float xD = xE - xS; float yD = yE - yS; float mod = 1.0f / ( xD * xD + yD * yD ); float gradPos = ( ( imageX - xS ) * xD + ( imageY - yS ) * yD ) * mod; float mag = gradPos > 0 ? gradPos < 1.0f ? gradPos : 1.0f : 0.0f; int colour = (int)( 255 * mag ); colour |= ( colour << 16 ) + ( colour << 8 ); return colour; }
Pour les accélérations, mettez en cache les valeurs de "direction" dérivées (indice: prémultiplier par le mag).
Ce problème comporte deux parties.
Étant donné deux couleurs A et B et un certain pourcentage p, déterminez quelle couleur se trouve p ‘pour cent du chemin’ de A à B.
À partir d’un point d’un plan, trouvez la projection orthogonale de ce point sur une ligne donnée.
La ligne donnée dans la partie 2 est votre ligne de dégradé. Pour tout point P, projetez-le sur la ligne de dégradé. Supposons que sa projection est R. Ensuite, déterminez la distance entre R et le sharepoint départ de votre segment de dégradé, sous forme de pourcentage de la longueur du segment de dégradé. Utilisez ce pourcentage dans votre fonction à partir de la partie 1 ci-dessus. C’est la couleur que P devrait être.
Notez que, contrairement à ce que d’autres personnes ont dit, vous ne pouvez pas simplement voir vos couleurs comme des nombres normaux dans votre fonction à partir de la partie 1. Cela ne fera presque certainement pas ce que vous voulez. Ce que vous faites dépend de l’espace colorimésortingque que vous utilisez. Si vous souhaitez un dégradé RVB, vous devez examiner séparément les composants de couleur rouge, vert et bleu.
Par exemple, si vous voulez une couleur “à mi-chemin entre” le rouge et le bleu purs, alors vous utilisez la notation hexadécimale.
ff 00 00
et
00 00 ff
Probablement la couleur que vous voulez est quelque chose comme
80 00 80
qui est une belle couleur pourpre. Vous devez établir une moyenne pour chaque composante de couleur séparément. Si vous essayez juste de faire la moyenne des nombres hexadécimaux 0xff0000 et 0x0000ff directement, vous obtenez 0x7F807F, qui est un gris moyen. Je suppose que cela explique au moins une partie du problème de votre photo ci-dessus.
Si vous êtes dans l’espace colorimésortingque HSV, vous pouvez également ajuster le composant de teinte uniquement et laisser les autres tels quels.