Trying to draw a vertical linear gradient using a map of colors, but only the first 9 colors are used: why?












0















(nota: a Minimal, Complete, and Verifiable example is provided at the end of this question)



Summary




  1. Context, Aim & Problem


  2. What I have already tried


  3. Pertinent sources explained


  4. Expected results, Actual results & Question


  5. Minimal, Complete, and Verifiable example



Context, Aim & Problem



I am trying to animate some pixels to generate a fire animation in Java. Each pixel is colored so that a vertical linear gradient, from white to yellow, yellow to red, and red to black, is drawn. This gradient goes from bottom to top of the canvas.



At the beginning of the execution, all pixels are black, except the white line which is defined by the coordinate y = height - 1, height being the height of the canvas. This white line is used to init the gradient ("white to yellow, yellow to ..., etc.").



The problem is that the gradient begins correctly, but it stops when the 9th color is used. Then only this color is used to fill my gradient and I don't know why.



What I have already tried



I have a map of RGB values which defines a gradient.



The idea to know which color to apply to a pixel called "A" is to retrieve the RGB of the pixel just below it, then get the ID of this RGB among all the RGB of my map. Then, I get the RGB under this ID + 1 in this same map and apply it to the pixel A.



So:




  1. I checked the function that returns the ID of the RGB, given this RGB: it seems to be OK since I don't have thrown any exception


  2. I checked if the buffered image I use is correctly updated. In other words: if the fact that a pixel has been colored really has the consequence to determine the color of the pixel above : it's OK too



Pertinent sources explained



Calling methods to draw the gradient



The idea is to set all pixels in black, except the bottom line which is white. Then, I iterate on each canvas' pixel and give it the color of its below direct vertical neighbor. More precisely, I give it the color whose ID = the ID of this neighbor pixel's color + 1, within my map of colors.



    Colors colors = new FireColors(new ArrayList<>());
gui.colorize(colors.getColorAtIndex(34), -1, -1); // Setting black anywhere
gui.colorize(colors.getColorAtIndex(0), -1, height - 1); // Setting white, in a lower line

try {
for(int y = height - 2; y >= 0; y--) {
for(int x = 0; x < width; x++) {
int below_pixel_rgb = gui.getRGBAtCoordinates(x, y + 1);
int index_of_found_color = colors.getIndexOfColor(below_pixel_rgb);
int index_of_color_to_apply = (index_of_found_color + 1) % colors.getSize();
gui.colorize(colors.getColorAtIndex(index_of_color_to_apply), x, y);
}
}
} catch (Exception e) {
System.err.println(e.getMessage());
}


How I color pixels



I'm just iterating over the canvas.



void colorize(Color color, int x_parameter, int y_parameter) {
for(int y = (y_parameter == -1 ? 0 : y_parameter); y <= (y_parameter == -1 ? this.getHeight() - 1 : y_parameter); y++) {
for(int x = (x_parameter == -1 ? 0 : x_parameter); x <= (x_parameter== -1 ? this.getWidth() - 1 : x_parameter); x++) {
buffered_image.setRGB(x, y, color.getRGB());
}
}
panel.repaint();
}


How do I find the index of the color of a pixel, within the list of colors?



int getIndexOfColor(int rgb) throws Exception {
for (int x = 0; x < colors.size(); x++) {
if(colors.get(x).getRGB() == rgb) {
return x;
}
}
throw new Exception("Color not found in the list!");
}


Expected results, Actual results & Question



I expect to have several vertical gradients (each from bottom to top). "Several" because my canvas' height is greater than the number of the colors of my gradients and because I use a modulo to choose the color to apply.



The actual results are: I get a gradient that begins from white to yellow, there are only 9 colors and that's all. No orange, no red, no black. Indeed: https://imgur.com/oQFJ52k



My question is: since the good ID is retrieved, and the good neighbor chosen for a given pixel, why is my gradient blocked to the 9th color? In other words: why, from a precise moment, aren't the good colors chosen?



Minimal, Complete, and Verifiable example



Launcher.java



import java.util.ArrayList;

public class Launcher {

public static void main(String args) {
int width = 150, height = 150;
Gui gui = new Gui(width, height);
gui.setUp("DOOM-like fire");
gui.setVisible(true);

Colors colors = new FireColors(new ArrayList<>());
gui.colorize(colors.getColorAtIndex(34), -1, -1); // Setting black anywhere
gui.colorize(colors.getColorAtIndex(0), -1, height - 1); // Setting white, in a lower line

try {
for(int y = height - 2; y >= 0; y--) {
for(int x = 0; x < width; x++) {
int below_pixel_rgb = gui.getRGBAtCoordinates(x, y + 1);
int index_of_found_color = colors.getIndexOfColor(below_pixel_rgb);
int index_of_color_to_apply = (index_of_found_color + 1) % colors.getSize();
gui.colorize(colors.getColorAtIndex(index_of_color_to_apply), x, y);
}
}
} catch (Exception e) {
System.err.println(e.getMessage());
}
}

}


Gui.java



import java.awt.*;
import javax.swing.*;
import java.awt.image.BufferedImage;

class Gui extends JFrame {

private JPanel panel;
private BufferedImage buffered_image;

Gui(int width, int height) {
buffered_image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
panel = new JPanel() {
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
graphics.drawImage(buffered_image, 0, 0, null);
}
};
}

void setUp(String title) {
setTitle(title);
setLayout(null);
setSize(buffered_image.getWidth(), buffered_image.getHeight());
setContentPane(panel);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}

void colorize(Color color, int x_parameter, int y_parameter) {
for(int y = (y_parameter == -1 ? 0 : y_parameter); y <= (y_parameter == -1 ? this.getHeight() - 1 : y_parameter); y++) {
for(int x = (x_parameter == -1 ? 0 : x_parameter); x <= (x_parameter== -1 ? this.getWidth() - 1 : x_parameter); x++) {
buffered_image.setRGB(x, y, color.getRGB());
}
}
panel.repaint();
}

int getRGBAtCoordinates(int x, int y) {
return buffered_image.getRGB(x, y);
}

}


Colors.java



import java.awt.Color;
import java.util.List;

abstract class Colors {
List<Color> colors;

Color getColorAtIndex(int index) {
return colors.get(index);
}

int getIndexOfColor(int rgb) throws Exception {
for (int x = 0; x < colors.size(); x++) {
if(colors.get(x).getRGB() == rgb) {
return x;
}
}
throw new Exception("Color not found in the list!");
}

int getSize() {
return colors.size();
}
}


FireColors.java



import java.awt.Color;
import java.util.List;

class FireColors extends Colors {

FireColors(List<Color> colors) {

this.colors = colors;

this.colors.add(new Color(255, 255, 255));
this.colors.add(new Color(239, 239, 199));
this.colors.add(new Color(223, 223, 159));
this.colors.add(new Color(207, 207, 111));
this.colors.add(new Color(183, 183, 55));
this.colors.add(new Color(183, 183, 47));
this.colors.add(new Color(183, 175, 47));
this.colors.add(new Color(191, 175, 47));
this.colors.add(new Color(191, 167, 39));
this.colors.add(new Color(191, 167, 39));
this.colors.add(new Color(191, 159, 31));
this.colors.add(new Color(191, 159, 31));
this.colors.add(new Color(199, 151, 31));
this.colors.add(new Color(199, 143, 23));
this.colors.add(new Color(199, 135, 23));
this.colors.add(new Color(207, 135, 23));
this.colors.add(new Color(207, 127, 15));
this.colors.add(new Color(207, 119, 15));
this.colors.add(new Color(207, 111, 15));
this.colors.add(new Color(215, 103, 15));
this.colors.add(new Color(215, 95, 7));
this.colors.add(new Color(223, 87, 7));
this.colors.add(new Color(223, 87, 7));
this.colors.add(new Color(223, 79, 7));
this.colors.add(new Color(199, 71, 7));
this.colors.add(new Color(191, 71, 7));
this.colors.add(new Color(175, 63, 7));
this.colors.add(new Color(159, 47, 7));
this.colors.add(new Color(143, 39, 7));
this.colors.add(new Color(119, 31, 7));
this.colors.add(new Color(103, 31, 7));
this.colors.add(new Color(87, 23, 7));
this.colors.add(new Color(71, 15, 7));
this.colors.add(new Color(47, 15, 7));
this.colors.add(new Color(7, 7, 7));

}

}









share|improve this question



























    0















    (nota: a Minimal, Complete, and Verifiable example is provided at the end of this question)



    Summary




    1. Context, Aim & Problem


    2. What I have already tried


    3. Pertinent sources explained


    4. Expected results, Actual results & Question


    5. Minimal, Complete, and Verifiable example



    Context, Aim & Problem



    I am trying to animate some pixels to generate a fire animation in Java. Each pixel is colored so that a vertical linear gradient, from white to yellow, yellow to red, and red to black, is drawn. This gradient goes from bottom to top of the canvas.



    At the beginning of the execution, all pixels are black, except the white line which is defined by the coordinate y = height - 1, height being the height of the canvas. This white line is used to init the gradient ("white to yellow, yellow to ..., etc.").



    The problem is that the gradient begins correctly, but it stops when the 9th color is used. Then only this color is used to fill my gradient and I don't know why.



    What I have already tried



    I have a map of RGB values which defines a gradient.



    The idea to know which color to apply to a pixel called "A" is to retrieve the RGB of the pixel just below it, then get the ID of this RGB among all the RGB of my map. Then, I get the RGB under this ID + 1 in this same map and apply it to the pixel A.



    So:




    1. I checked the function that returns the ID of the RGB, given this RGB: it seems to be OK since I don't have thrown any exception


    2. I checked if the buffered image I use is correctly updated. In other words: if the fact that a pixel has been colored really has the consequence to determine the color of the pixel above : it's OK too



    Pertinent sources explained



    Calling methods to draw the gradient



    The idea is to set all pixels in black, except the bottom line which is white. Then, I iterate on each canvas' pixel and give it the color of its below direct vertical neighbor. More precisely, I give it the color whose ID = the ID of this neighbor pixel's color + 1, within my map of colors.



        Colors colors = new FireColors(new ArrayList<>());
    gui.colorize(colors.getColorAtIndex(34), -1, -1); // Setting black anywhere
    gui.colorize(colors.getColorAtIndex(0), -1, height - 1); // Setting white, in a lower line

    try {
    for(int y = height - 2; y >= 0; y--) {
    for(int x = 0; x < width; x++) {
    int below_pixel_rgb = gui.getRGBAtCoordinates(x, y + 1);
    int index_of_found_color = colors.getIndexOfColor(below_pixel_rgb);
    int index_of_color_to_apply = (index_of_found_color + 1) % colors.getSize();
    gui.colorize(colors.getColorAtIndex(index_of_color_to_apply), x, y);
    }
    }
    } catch (Exception e) {
    System.err.println(e.getMessage());
    }


    How I color pixels



    I'm just iterating over the canvas.



    void colorize(Color color, int x_parameter, int y_parameter) {
    for(int y = (y_parameter == -1 ? 0 : y_parameter); y <= (y_parameter == -1 ? this.getHeight() - 1 : y_parameter); y++) {
    for(int x = (x_parameter == -1 ? 0 : x_parameter); x <= (x_parameter== -1 ? this.getWidth() - 1 : x_parameter); x++) {
    buffered_image.setRGB(x, y, color.getRGB());
    }
    }
    panel.repaint();
    }


    How do I find the index of the color of a pixel, within the list of colors?



    int getIndexOfColor(int rgb) throws Exception {
    for (int x = 0; x < colors.size(); x++) {
    if(colors.get(x).getRGB() == rgb) {
    return x;
    }
    }
    throw new Exception("Color not found in the list!");
    }


    Expected results, Actual results & Question



    I expect to have several vertical gradients (each from bottom to top). "Several" because my canvas' height is greater than the number of the colors of my gradients and because I use a modulo to choose the color to apply.



    The actual results are: I get a gradient that begins from white to yellow, there are only 9 colors and that's all. No orange, no red, no black. Indeed: https://imgur.com/oQFJ52k



    My question is: since the good ID is retrieved, and the good neighbor chosen for a given pixel, why is my gradient blocked to the 9th color? In other words: why, from a precise moment, aren't the good colors chosen?



    Minimal, Complete, and Verifiable example



    Launcher.java



    import java.util.ArrayList;

    public class Launcher {

    public static void main(String args) {
    int width = 150, height = 150;
    Gui gui = new Gui(width, height);
    gui.setUp("DOOM-like fire");
    gui.setVisible(true);

    Colors colors = new FireColors(new ArrayList<>());
    gui.colorize(colors.getColorAtIndex(34), -1, -1); // Setting black anywhere
    gui.colorize(colors.getColorAtIndex(0), -1, height - 1); // Setting white, in a lower line

    try {
    for(int y = height - 2; y >= 0; y--) {
    for(int x = 0; x < width; x++) {
    int below_pixel_rgb = gui.getRGBAtCoordinates(x, y + 1);
    int index_of_found_color = colors.getIndexOfColor(below_pixel_rgb);
    int index_of_color_to_apply = (index_of_found_color + 1) % colors.getSize();
    gui.colorize(colors.getColorAtIndex(index_of_color_to_apply), x, y);
    }
    }
    } catch (Exception e) {
    System.err.println(e.getMessage());
    }
    }

    }


    Gui.java



    import java.awt.*;
    import javax.swing.*;
    import java.awt.image.BufferedImage;

    class Gui extends JFrame {

    private JPanel panel;
    private BufferedImage buffered_image;

    Gui(int width, int height) {
    buffered_image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    panel = new JPanel() {
    public void paintComponent(Graphics graphics) {
    super.paintComponent(graphics);
    graphics.drawImage(buffered_image, 0, 0, null);
    }
    };
    }

    void setUp(String title) {
    setTitle(title);
    setLayout(null);
    setSize(buffered_image.getWidth(), buffered_image.getHeight());
    setContentPane(panel);
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    void colorize(Color color, int x_parameter, int y_parameter) {
    for(int y = (y_parameter == -1 ? 0 : y_parameter); y <= (y_parameter == -1 ? this.getHeight() - 1 : y_parameter); y++) {
    for(int x = (x_parameter == -1 ? 0 : x_parameter); x <= (x_parameter== -1 ? this.getWidth() - 1 : x_parameter); x++) {
    buffered_image.setRGB(x, y, color.getRGB());
    }
    }
    panel.repaint();
    }

    int getRGBAtCoordinates(int x, int y) {
    return buffered_image.getRGB(x, y);
    }

    }


    Colors.java



    import java.awt.Color;
    import java.util.List;

    abstract class Colors {
    List<Color> colors;

    Color getColorAtIndex(int index) {
    return colors.get(index);
    }

    int getIndexOfColor(int rgb) throws Exception {
    for (int x = 0; x < colors.size(); x++) {
    if(colors.get(x).getRGB() == rgb) {
    return x;
    }
    }
    throw new Exception("Color not found in the list!");
    }

    int getSize() {
    return colors.size();
    }
    }


    FireColors.java



    import java.awt.Color;
    import java.util.List;

    class FireColors extends Colors {

    FireColors(List<Color> colors) {

    this.colors = colors;

    this.colors.add(new Color(255, 255, 255));
    this.colors.add(new Color(239, 239, 199));
    this.colors.add(new Color(223, 223, 159));
    this.colors.add(new Color(207, 207, 111));
    this.colors.add(new Color(183, 183, 55));
    this.colors.add(new Color(183, 183, 47));
    this.colors.add(new Color(183, 175, 47));
    this.colors.add(new Color(191, 175, 47));
    this.colors.add(new Color(191, 167, 39));
    this.colors.add(new Color(191, 167, 39));
    this.colors.add(new Color(191, 159, 31));
    this.colors.add(new Color(191, 159, 31));
    this.colors.add(new Color(199, 151, 31));
    this.colors.add(new Color(199, 143, 23));
    this.colors.add(new Color(199, 135, 23));
    this.colors.add(new Color(207, 135, 23));
    this.colors.add(new Color(207, 127, 15));
    this.colors.add(new Color(207, 119, 15));
    this.colors.add(new Color(207, 111, 15));
    this.colors.add(new Color(215, 103, 15));
    this.colors.add(new Color(215, 95, 7));
    this.colors.add(new Color(223, 87, 7));
    this.colors.add(new Color(223, 87, 7));
    this.colors.add(new Color(223, 79, 7));
    this.colors.add(new Color(199, 71, 7));
    this.colors.add(new Color(191, 71, 7));
    this.colors.add(new Color(175, 63, 7));
    this.colors.add(new Color(159, 47, 7));
    this.colors.add(new Color(143, 39, 7));
    this.colors.add(new Color(119, 31, 7));
    this.colors.add(new Color(103, 31, 7));
    this.colors.add(new Color(87, 23, 7));
    this.colors.add(new Color(71, 15, 7));
    this.colors.add(new Color(47, 15, 7));
    this.colors.add(new Color(7, 7, 7));

    }

    }









    share|improve this question

























      0












      0








      0








      (nota: a Minimal, Complete, and Verifiable example is provided at the end of this question)



      Summary




      1. Context, Aim & Problem


      2. What I have already tried


      3. Pertinent sources explained


      4. Expected results, Actual results & Question


      5. Minimal, Complete, and Verifiable example



      Context, Aim & Problem



      I am trying to animate some pixels to generate a fire animation in Java. Each pixel is colored so that a vertical linear gradient, from white to yellow, yellow to red, and red to black, is drawn. This gradient goes from bottom to top of the canvas.



      At the beginning of the execution, all pixels are black, except the white line which is defined by the coordinate y = height - 1, height being the height of the canvas. This white line is used to init the gradient ("white to yellow, yellow to ..., etc.").



      The problem is that the gradient begins correctly, but it stops when the 9th color is used. Then only this color is used to fill my gradient and I don't know why.



      What I have already tried



      I have a map of RGB values which defines a gradient.



      The idea to know which color to apply to a pixel called "A" is to retrieve the RGB of the pixel just below it, then get the ID of this RGB among all the RGB of my map. Then, I get the RGB under this ID + 1 in this same map and apply it to the pixel A.



      So:




      1. I checked the function that returns the ID of the RGB, given this RGB: it seems to be OK since I don't have thrown any exception


      2. I checked if the buffered image I use is correctly updated. In other words: if the fact that a pixel has been colored really has the consequence to determine the color of the pixel above : it's OK too



      Pertinent sources explained



      Calling methods to draw the gradient



      The idea is to set all pixels in black, except the bottom line which is white. Then, I iterate on each canvas' pixel and give it the color of its below direct vertical neighbor. More precisely, I give it the color whose ID = the ID of this neighbor pixel's color + 1, within my map of colors.



          Colors colors = new FireColors(new ArrayList<>());
      gui.colorize(colors.getColorAtIndex(34), -1, -1); // Setting black anywhere
      gui.colorize(colors.getColorAtIndex(0), -1, height - 1); // Setting white, in a lower line

      try {
      for(int y = height - 2; y >= 0; y--) {
      for(int x = 0; x < width; x++) {
      int below_pixel_rgb = gui.getRGBAtCoordinates(x, y + 1);
      int index_of_found_color = colors.getIndexOfColor(below_pixel_rgb);
      int index_of_color_to_apply = (index_of_found_color + 1) % colors.getSize();
      gui.colorize(colors.getColorAtIndex(index_of_color_to_apply), x, y);
      }
      }
      } catch (Exception e) {
      System.err.println(e.getMessage());
      }


      How I color pixels



      I'm just iterating over the canvas.



      void colorize(Color color, int x_parameter, int y_parameter) {
      for(int y = (y_parameter == -1 ? 0 : y_parameter); y <= (y_parameter == -1 ? this.getHeight() - 1 : y_parameter); y++) {
      for(int x = (x_parameter == -1 ? 0 : x_parameter); x <= (x_parameter== -1 ? this.getWidth() - 1 : x_parameter); x++) {
      buffered_image.setRGB(x, y, color.getRGB());
      }
      }
      panel.repaint();
      }


      How do I find the index of the color of a pixel, within the list of colors?



      int getIndexOfColor(int rgb) throws Exception {
      for (int x = 0; x < colors.size(); x++) {
      if(colors.get(x).getRGB() == rgb) {
      return x;
      }
      }
      throw new Exception("Color not found in the list!");
      }


      Expected results, Actual results & Question



      I expect to have several vertical gradients (each from bottom to top). "Several" because my canvas' height is greater than the number of the colors of my gradients and because I use a modulo to choose the color to apply.



      The actual results are: I get a gradient that begins from white to yellow, there are only 9 colors and that's all. No orange, no red, no black. Indeed: https://imgur.com/oQFJ52k



      My question is: since the good ID is retrieved, and the good neighbor chosen for a given pixel, why is my gradient blocked to the 9th color? In other words: why, from a precise moment, aren't the good colors chosen?



      Minimal, Complete, and Verifiable example



      Launcher.java



      import java.util.ArrayList;

      public class Launcher {

      public static void main(String args) {
      int width = 150, height = 150;
      Gui gui = new Gui(width, height);
      gui.setUp("DOOM-like fire");
      gui.setVisible(true);

      Colors colors = new FireColors(new ArrayList<>());
      gui.colorize(colors.getColorAtIndex(34), -1, -1); // Setting black anywhere
      gui.colorize(colors.getColorAtIndex(0), -1, height - 1); // Setting white, in a lower line

      try {
      for(int y = height - 2; y >= 0; y--) {
      for(int x = 0; x < width; x++) {
      int below_pixel_rgb = gui.getRGBAtCoordinates(x, y + 1);
      int index_of_found_color = colors.getIndexOfColor(below_pixel_rgb);
      int index_of_color_to_apply = (index_of_found_color + 1) % colors.getSize();
      gui.colorize(colors.getColorAtIndex(index_of_color_to_apply), x, y);
      }
      }
      } catch (Exception e) {
      System.err.println(e.getMessage());
      }
      }

      }


      Gui.java



      import java.awt.*;
      import javax.swing.*;
      import java.awt.image.BufferedImage;

      class Gui extends JFrame {

      private JPanel panel;
      private BufferedImage buffered_image;

      Gui(int width, int height) {
      buffered_image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
      panel = new JPanel() {
      public void paintComponent(Graphics graphics) {
      super.paintComponent(graphics);
      graphics.drawImage(buffered_image, 0, 0, null);
      }
      };
      }

      void setUp(String title) {
      setTitle(title);
      setLayout(null);
      setSize(buffered_image.getWidth(), buffered_image.getHeight());
      setContentPane(panel);
      setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      }

      void colorize(Color color, int x_parameter, int y_parameter) {
      for(int y = (y_parameter == -1 ? 0 : y_parameter); y <= (y_parameter == -1 ? this.getHeight() - 1 : y_parameter); y++) {
      for(int x = (x_parameter == -1 ? 0 : x_parameter); x <= (x_parameter== -1 ? this.getWidth() - 1 : x_parameter); x++) {
      buffered_image.setRGB(x, y, color.getRGB());
      }
      }
      panel.repaint();
      }

      int getRGBAtCoordinates(int x, int y) {
      return buffered_image.getRGB(x, y);
      }

      }


      Colors.java



      import java.awt.Color;
      import java.util.List;

      abstract class Colors {
      List<Color> colors;

      Color getColorAtIndex(int index) {
      return colors.get(index);
      }

      int getIndexOfColor(int rgb) throws Exception {
      for (int x = 0; x < colors.size(); x++) {
      if(colors.get(x).getRGB() == rgb) {
      return x;
      }
      }
      throw new Exception("Color not found in the list!");
      }

      int getSize() {
      return colors.size();
      }
      }


      FireColors.java



      import java.awt.Color;
      import java.util.List;

      class FireColors extends Colors {

      FireColors(List<Color> colors) {

      this.colors = colors;

      this.colors.add(new Color(255, 255, 255));
      this.colors.add(new Color(239, 239, 199));
      this.colors.add(new Color(223, 223, 159));
      this.colors.add(new Color(207, 207, 111));
      this.colors.add(new Color(183, 183, 55));
      this.colors.add(new Color(183, 183, 47));
      this.colors.add(new Color(183, 175, 47));
      this.colors.add(new Color(191, 175, 47));
      this.colors.add(new Color(191, 167, 39));
      this.colors.add(new Color(191, 167, 39));
      this.colors.add(new Color(191, 159, 31));
      this.colors.add(new Color(191, 159, 31));
      this.colors.add(new Color(199, 151, 31));
      this.colors.add(new Color(199, 143, 23));
      this.colors.add(new Color(199, 135, 23));
      this.colors.add(new Color(207, 135, 23));
      this.colors.add(new Color(207, 127, 15));
      this.colors.add(new Color(207, 119, 15));
      this.colors.add(new Color(207, 111, 15));
      this.colors.add(new Color(215, 103, 15));
      this.colors.add(new Color(215, 95, 7));
      this.colors.add(new Color(223, 87, 7));
      this.colors.add(new Color(223, 87, 7));
      this.colors.add(new Color(223, 79, 7));
      this.colors.add(new Color(199, 71, 7));
      this.colors.add(new Color(191, 71, 7));
      this.colors.add(new Color(175, 63, 7));
      this.colors.add(new Color(159, 47, 7));
      this.colors.add(new Color(143, 39, 7));
      this.colors.add(new Color(119, 31, 7));
      this.colors.add(new Color(103, 31, 7));
      this.colors.add(new Color(87, 23, 7));
      this.colors.add(new Color(71, 15, 7));
      this.colors.add(new Color(47, 15, 7));
      this.colors.add(new Color(7, 7, 7));

      }

      }









      share|improve this question














      (nota: a Minimal, Complete, and Verifiable example is provided at the end of this question)



      Summary




      1. Context, Aim & Problem


      2. What I have already tried


      3. Pertinent sources explained


      4. Expected results, Actual results & Question


      5. Minimal, Complete, and Verifiable example



      Context, Aim & Problem



      I am trying to animate some pixels to generate a fire animation in Java. Each pixel is colored so that a vertical linear gradient, from white to yellow, yellow to red, and red to black, is drawn. This gradient goes from bottom to top of the canvas.



      At the beginning of the execution, all pixels are black, except the white line which is defined by the coordinate y = height - 1, height being the height of the canvas. This white line is used to init the gradient ("white to yellow, yellow to ..., etc.").



      The problem is that the gradient begins correctly, but it stops when the 9th color is used. Then only this color is used to fill my gradient and I don't know why.



      What I have already tried



      I have a map of RGB values which defines a gradient.



      The idea to know which color to apply to a pixel called "A" is to retrieve the RGB of the pixel just below it, then get the ID of this RGB among all the RGB of my map. Then, I get the RGB under this ID + 1 in this same map and apply it to the pixel A.



      So:




      1. I checked the function that returns the ID of the RGB, given this RGB: it seems to be OK since I don't have thrown any exception


      2. I checked if the buffered image I use is correctly updated. In other words: if the fact that a pixel has been colored really has the consequence to determine the color of the pixel above : it's OK too



      Pertinent sources explained



      Calling methods to draw the gradient



      The idea is to set all pixels in black, except the bottom line which is white. Then, I iterate on each canvas' pixel and give it the color of its below direct vertical neighbor. More precisely, I give it the color whose ID = the ID of this neighbor pixel's color + 1, within my map of colors.



          Colors colors = new FireColors(new ArrayList<>());
      gui.colorize(colors.getColorAtIndex(34), -1, -1); // Setting black anywhere
      gui.colorize(colors.getColorAtIndex(0), -1, height - 1); // Setting white, in a lower line

      try {
      for(int y = height - 2; y >= 0; y--) {
      for(int x = 0; x < width; x++) {
      int below_pixel_rgb = gui.getRGBAtCoordinates(x, y + 1);
      int index_of_found_color = colors.getIndexOfColor(below_pixel_rgb);
      int index_of_color_to_apply = (index_of_found_color + 1) % colors.getSize();
      gui.colorize(colors.getColorAtIndex(index_of_color_to_apply), x, y);
      }
      }
      } catch (Exception e) {
      System.err.println(e.getMessage());
      }


      How I color pixels



      I'm just iterating over the canvas.



      void colorize(Color color, int x_parameter, int y_parameter) {
      for(int y = (y_parameter == -1 ? 0 : y_parameter); y <= (y_parameter == -1 ? this.getHeight() - 1 : y_parameter); y++) {
      for(int x = (x_parameter == -1 ? 0 : x_parameter); x <= (x_parameter== -1 ? this.getWidth() - 1 : x_parameter); x++) {
      buffered_image.setRGB(x, y, color.getRGB());
      }
      }
      panel.repaint();
      }


      How do I find the index of the color of a pixel, within the list of colors?



      int getIndexOfColor(int rgb) throws Exception {
      for (int x = 0; x < colors.size(); x++) {
      if(colors.get(x).getRGB() == rgb) {
      return x;
      }
      }
      throw new Exception("Color not found in the list!");
      }


      Expected results, Actual results & Question



      I expect to have several vertical gradients (each from bottom to top). "Several" because my canvas' height is greater than the number of the colors of my gradients and because I use a modulo to choose the color to apply.



      The actual results are: I get a gradient that begins from white to yellow, there are only 9 colors and that's all. No orange, no red, no black. Indeed: https://imgur.com/oQFJ52k



      My question is: since the good ID is retrieved, and the good neighbor chosen for a given pixel, why is my gradient blocked to the 9th color? In other words: why, from a precise moment, aren't the good colors chosen?



      Minimal, Complete, and Verifiable example



      Launcher.java



      import java.util.ArrayList;

      public class Launcher {

      public static void main(String args) {
      int width = 150, height = 150;
      Gui gui = new Gui(width, height);
      gui.setUp("DOOM-like fire");
      gui.setVisible(true);

      Colors colors = new FireColors(new ArrayList<>());
      gui.colorize(colors.getColorAtIndex(34), -1, -1); // Setting black anywhere
      gui.colorize(colors.getColorAtIndex(0), -1, height - 1); // Setting white, in a lower line

      try {
      for(int y = height - 2; y >= 0; y--) {
      for(int x = 0; x < width; x++) {
      int below_pixel_rgb = gui.getRGBAtCoordinates(x, y + 1);
      int index_of_found_color = colors.getIndexOfColor(below_pixel_rgb);
      int index_of_color_to_apply = (index_of_found_color + 1) % colors.getSize();
      gui.colorize(colors.getColorAtIndex(index_of_color_to_apply), x, y);
      }
      }
      } catch (Exception e) {
      System.err.println(e.getMessage());
      }
      }

      }


      Gui.java



      import java.awt.*;
      import javax.swing.*;
      import java.awt.image.BufferedImage;

      class Gui extends JFrame {

      private JPanel panel;
      private BufferedImage buffered_image;

      Gui(int width, int height) {
      buffered_image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
      panel = new JPanel() {
      public void paintComponent(Graphics graphics) {
      super.paintComponent(graphics);
      graphics.drawImage(buffered_image, 0, 0, null);
      }
      };
      }

      void setUp(String title) {
      setTitle(title);
      setLayout(null);
      setSize(buffered_image.getWidth(), buffered_image.getHeight());
      setContentPane(panel);
      setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      }

      void colorize(Color color, int x_parameter, int y_parameter) {
      for(int y = (y_parameter == -1 ? 0 : y_parameter); y <= (y_parameter == -1 ? this.getHeight() - 1 : y_parameter); y++) {
      for(int x = (x_parameter == -1 ? 0 : x_parameter); x <= (x_parameter== -1 ? this.getWidth() - 1 : x_parameter); x++) {
      buffered_image.setRGB(x, y, color.getRGB());
      }
      }
      panel.repaint();
      }

      int getRGBAtCoordinates(int x, int y) {
      return buffered_image.getRGB(x, y);
      }

      }


      Colors.java



      import java.awt.Color;
      import java.util.List;

      abstract class Colors {
      List<Color> colors;

      Color getColorAtIndex(int index) {
      return colors.get(index);
      }

      int getIndexOfColor(int rgb) throws Exception {
      for (int x = 0; x < colors.size(); x++) {
      if(colors.get(x).getRGB() == rgb) {
      return x;
      }
      }
      throw new Exception("Color not found in the list!");
      }

      int getSize() {
      return colors.size();
      }
      }


      FireColors.java



      import java.awt.Color;
      import java.util.List;

      class FireColors extends Colors {

      FireColors(List<Color> colors) {

      this.colors = colors;

      this.colors.add(new Color(255, 255, 255));
      this.colors.add(new Color(239, 239, 199));
      this.colors.add(new Color(223, 223, 159));
      this.colors.add(new Color(207, 207, 111));
      this.colors.add(new Color(183, 183, 55));
      this.colors.add(new Color(183, 183, 47));
      this.colors.add(new Color(183, 175, 47));
      this.colors.add(new Color(191, 175, 47));
      this.colors.add(new Color(191, 167, 39));
      this.colors.add(new Color(191, 167, 39));
      this.colors.add(new Color(191, 159, 31));
      this.colors.add(new Color(191, 159, 31));
      this.colors.add(new Color(199, 151, 31));
      this.colors.add(new Color(199, 143, 23));
      this.colors.add(new Color(199, 135, 23));
      this.colors.add(new Color(207, 135, 23));
      this.colors.add(new Color(207, 127, 15));
      this.colors.add(new Color(207, 119, 15));
      this.colors.add(new Color(207, 111, 15));
      this.colors.add(new Color(215, 103, 15));
      this.colors.add(new Color(215, 95, 7));
      this.colors.add(new Color(223, 87, 7));
      this.colors.add(new Color(223, 87, 7));
      this.colors.add(new Color(223, 79, 7));
      this.colors.add(new Color(199, 71, 7));
      this.colors.add(new Color(191, 71, 7));
      this.colors.add(new Color(175, 63, 7));
      this.colors.add(new Color(159, 47, 7));
      this.colors.add(new Color(143, 39, 7));
      this.colors.add(new Color(119, 31, 7));
      this.colors.add(new Color(103, 31, 7));
      this.colors.add(new Color(87, 23, 7));
      this.colors.add(new Color(71, 15, 7));
      this.colors.add(new Color(47, 15, 7));
      this.colors.add(new Color(7, 7, 7));

      }

      }






      java colors bufferedimage






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jan 1 at 14:55









      JarsOfJam-SchedulerJarsOfJam-Scheduler

      211315




      211315
























          1 Answer
          1






          active

          oldest

          votes


















          2














          Your problem is that FireColors contains duplicate colors:



          // FireColors, lines 20 and 21:
          this.colors.add(new Color(191, 167, 39));
          this.colors.add(new Color(191, 167, 39));
          // more duplicate colors found later on!


          The problem is together with your color selection algorithm:



          // Launcher lines 20 to 22:
          int below_pixel_rgb = gui.getRGBAtCoordinates(x, y + 1);
          int index_of_found_color = colors.getIndexOfColor(below_pixel_rgb);
          int index_of_color_to_apply = (index_of_found_color + 1) % colors.getSize();


          For the 8th line, it reads the color from the line below it, finds its index (7), adds one and colors that line with the color #8.



          For the 9th line, it reads the color from the line below it, finds its index (8), adds one and colors that line with the color #9 (which is the same as color #8)



          For the 10th line, it reads the color from the line below it, finds its index (8, because getIndexOfColor() returns the first found index, which is 8, not 9!), adds one and colors that line with the color #9 (which is the same as color #8)



          To fix it, you should either redesign your color choosing algorithm or make your FireColor colors unique.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53996450%2ftrying-to-draw-a-vertical-linear-gradient-using-a-map-of-colors-but-only-the-fi%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            2














            Your problem is that FireColors contains duplicate colors:



            // FireColors, lines 20 and 21:
            this.colors.add(new Color(191, 167, 39));
            this.colors.add(new Color(191, 167, 39));
            // more duplicate colors found later on!


            The problem is together with your color selection algorithm:



            // Launcher lines 20 to 22:
            int below_pixel_rgb = gui.getRGBAtCoordinates(x, y + 1);
            int index_of_found_color = colors.getIndexOfColor(below_pixel_rgb);
            int index_of_color_to_apply = (index_of_found_color + 1) % colors.getSize();


            For the 8th line, it reads the color from the line below it, finds its index (7), adds one and colors that line with the color #8.



            For the 9th line, it reads the color from the line below it, finds its index (8), adds one and colors that line with the color #9 (which is the same as color #8)



            For the 10th line, it reads the color from the line below it, finds its index (8, because getIndexOfColor() returns the first found index, which is 8, not 9!), adds one and colors that line with the color #9 (which is the same as color #8)



            To fix it, you should either redesign your color choosing algorithm or make your FireColor colors unique.






            share|improve this answer




























              2














              Your problem is that FireColors contains duplicate colors:



              // FireColors, lines 20 and 21:
              this.colors.add(new Color(191, 167, 39));
              this.colors.add(new Color(191, 167, 39));
              // more duplicate colors found later on!


              The problem is together with your color selection algorithm:



              // Launcher lines 20 to 22:
              int below_pixel_rgb = gui.getRGBAtCoordinates(x, y + 1);
              int index_of_found_color = colors.getIndexOfColor(below_pixel_rgb);
              int index_of_color_to_apply = (index_of_found_color + 1) % colors.getSize();


              For the 8th line, it reads the color from the line below it, finds its index (7), adds one and colors that line with the color #8.



              For the 9th line, it reads the color from the line below it, finds its index (8), adds one and colors that line with the color #9 (which is the same as color #8)



              For the 10th line, it reads the color from the line below it, finds its index (8, because getIndexOfColor() returns the first found index, which is 8, not 9!), adds one and colors that line with the color #9 (which is the same as color #8)



              To fix it, you should either redesign your color choosing algorithm or make your FireColor colors unique.






              share|improve this answer


























                2












                2








                2







                Your problem is that FireColors contains duplicate colors:



                // FireColors, lines 20 and 21:
                this.colors.add(new Color(191, 167, 39));
                this.colors.add(new Color(191, 167, 39));
                // more duplicate colors found later on!


                The problem is together with your color selection algorithm:



                // Launcher lines 20 to 22:
                int below_pixel_rgb = gui.getRGBAtCoordinates(x, y + 1);
                int index_of_found_color = colors.getIndexOfColor(below_pixel_rgb);
                int index_of_color_to_apply = (index_of_found_color + 1) % colors.getSize();


                For the 8th line, it reads the color from the line below it, finds its index (7), adds one and colors that line with the color #8.



                For the 9th line, it reads the color from the line below it, finds its index (8), adds one and colors that line with the color #9 (which is the same as color #8)



                For the 10th line, it reads the color from the line below it, finds its index (8, because getIndexOfColor() returns the first found index, which is 8, not 9!), adds one and colors that line with the color #9 (which is the same as color #8)



                To fix it, you should either redesign your color choosing algorithm or make your FireColor colors unique.






                share|improve this answer













                Your problem is that FireColors contains duplicate colors:



                // FireColors, lines 20 and 21:
                this.colors.add(new Color(191, 167, 39));
                this.colors.add(new Color(191, 167, 39));
                // more duplicate colors found later on!


                The problem is together with your color selection algorithm:



                // Launcher lines 20 to 22:
                int below_pixel_rgb = gui.getRGBAtCoordinates(x, y + 1);
                int index_of_found_color = colors.getIndexOfColor(below_pixel_rgb);
                int index_of_color_to_apply = (index_of_found_color + 1) % colors.getSize();


                For the 8th line, it reads the color from the line below it, finds its index (7), adds one and colors that line with the color #8.



                For the 9th line, it reads the color from the line below it, finds its index (8), adds one and colors that line with the color #9 (which is the same as color #8)



                For the 10th line, it reads the color from the line below it, finds its index (8, because getIndexOfColor() returns the first found index, which is 8, not 9!), adds one and colors that line with the color #9 (which is the same as color #8)



                To fix it, you should either redesign your color choosing algorithm or make your FireColor colors unique.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jan 1 at 19:51









                Thomas KlägerThomas Kläger

                6,6252818




                6,6252818
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53996450%2ftrying-to-draw-a-vertical-linear-gradient-using-a-map-of-colors-but-only-the-fi%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    'app-layout' is not a known element: how to share Component with different Modules

                    android studio warns about leanback feature tag usage required on manifest while using Unity exported app?

                    WPF add header to Image with URL pettitions [duplicate]