0

I am trying to make it so that the position of a pixel in an image (int i, int j) determines the color of that pixel. This is for an explosion effect in a java2d game I want to be extra cool by making the colors of the explosion depend on the position of the explosion. What I am doing currently is creating an ArrayList of colors then using i*j as index, testing this out on a 1000x1000 image shows a mirroring along the diagonal, naturally because i*j = j*i around the diagonal as show below.

Knowing that i=0, j=999 is the 1000th pixel while i=999, j=0 is the 999001th pixel how would you get a mapping f(i,j) != f(j,i) of pixels to colors without first storing the colors in a list? The color ordering is very important, that is to say colors are constructed using R,0,0 then 0,G,0 then 0,0,B

Question wasn't clear apparently. Notice getAllColors, it creates the colors in order and adds them to the list, notice g2d.setColor(i*j), it sets the color in order except it mirrors along the diagonal. I want to know if I can map the colors to an index(in order) without storing it in a list while avoiding mirroring along the diagonal.

Full MCVE

public class AllColors extends JPanel {

private int width, height;
private double colorIncrement;
private List<Color> colors;

public AllColors(int width, int height) {
    this.width = width;
    this.height = height;
    this.colorIncrement = 1.0 / Math.pow(1.0 * width * height, 1.0 / 3);
    this.colors = new ArrayList<>(width * height);
    getAllColors();
}

@Override
@Transient
public Color getBackground() {
    return Color.black;
}

@Override
@Transient
public Dimension getPreferredSize() {
    return new Dimension(width, height);
}

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g.create();
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    for (int i = 0; i < width; i++) {
        for (int j = 0; j < height; j++) {
            // Notice i*j= j*i around diagonal, the problem
            g2d.setColor(colors.get(i * j));
            g2d.fillRect(i, j, 1, 1);
        }
    }
}

private void getAllColors() {
    for (float R = 0; R < 1.0; R += colorIncrement)
        for (float G = 0; G < 1.0; G += colorIncrement)
            for (float B = 0; B < 1.0; B += colorIncrement)
                colors.add(new Color(R, G, B));
}

public static void main(String[] args) {
    JFrame frame = new JFrame();
    AllColors allColors = new AllColors(800, 800);

    frame.getContentPane().add(allColors);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.pack();
    frame.setVisible(true);
}

}

enter image description here

durron597
  • 31,968
  • 17
  • 99
  • 158
arynaq
  • 6,710
  • 9
  • 44
  • 74

2 Answers2

0

In the double loop check when i=j then skip the payload.

Micromega
  • 12,486
  • 7
  • 35
  • 72
0

Knowing that i=0, j=999 is the 1000th pixel while i=999, j=0 is the 999001th pixel how would you get a mapping f(i,j) != f(j,i) of pixels to colors without first storing the colors in a list?

pixel = i * 1000 + j + 1;

As far as storing them in a list is concerned, that may be your best approach, since precalculation can often make things faster. Though I would probably do a two dimensional array. Like:

private void getAllColors() {
    colors = new Color[1000][1000];
    int i = 0; int j = 0;
    loop:
    for (float R = 0; R < 1.0; R += colorIncrement) {
        for (float G = 0; G < 1.0; G += colorIncrement) {
            for (float B = 0; B < 1.0; B += colorIncrement) {
                colors[i++][j] = new Color(R, G, B));
                if (i == 1000) {
                    j++;
                    i = 0;
                    if (j == 1000) break loop;
                }
            }
        }
    }
}
durron597
  • 31,968
  • 17
  • 99
  • 158