How to make a better nested loop for every single pixel?

188 Views Asked by At

What i'm trying to create is high resolution metaballs. Here is my algorithm:

public constructor(){
        this.image = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB);
        this.rgbRaster = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
        this.width = getWidth();
        this.height = getHeight();
}

private void updateRaster() {
        int red = c.getRed(), green = c.getGreen(), blue = c.getBlue();

        for (int y = 0; y < height; y++)
            for (int x = 0; x < width; x++) {
                var sum = 0f;
                for (Blob b : blobs)
                    sum += getSum(x, y, b);

                sum = Math.min(sum, 255) / 255f;

                rgbRaster[(width * y) + x] = ((0xFF) << 24) | (((int) (sum * red) & 0xFF) << 16) |
                        (((int) (sum * green) & 0xFF) << 8) | (((int) (sum * blue)) & 0xFF);
            }
    }
private float getSum(int x, int y, Blob b) {
        var d = Point.distance(x, y, b.pos.x, b.pos.y);
        return (float) map(1000f * b.r / d, 0, this.maxDist, 0, 255);
    }

private double map(double n, double start1, double stop1, double start2, double stop2) {
        return (n - start1) / (stop1 - start1) * (stop2 - start2) + start2;
    }

Blob class is pretty simple it's just a ball that bounces off the screen:

public class Blob {
    public Vector2D pos;
    public Vector2D vel;
    public float r;

    public Blob(Vector2D pos, Vector2D vel, float r) {
        this.pos = pos;
        this.vel = vel;
        this.r = r;
    }

    public void update(float w, float h) {
        this.pos.add(vel);
        this.bounds(w, h);
    }

    public void draw(Graphics2D g) {
        g.fill(new Ellipse2D.Double(this.pos.x - r, this.pos.y - r, r * 2, r * 2));
    }

    private void bounds(float w, float h) {
        if (this.pos.x + r > w || this.pos.x - r < 0) this.vel.mult(new Vector2D(-1, 1));
        if (this.pos.y + r > h || this.pos.y - r < 0) this.vel.mult(new Vector2D(1, -1));
    }
}

The problem is that there are too many iterations in nasted loops and it causes major freezes. I cannot figure out other way of cheking distanse from every single pixel of the screen to the center point of all blobs, so with high resolution picture and lots of blobs it makes it a slideshow. Also I know that converting everything into a BufferedImage is not a perfect idea but i don't know other ways of converting raster into a graphics object. Thanks in advance for your help) (Edit: getSum() finds a sum of all distanses to all blobs, maps it to color range, and limits it to 255 this function is certainly not an issue but a little bit complicated to understand that's why i didn't include it)(Edit 2: Thanks to @ThatOtherGuy now this way more optimized but probably there a some other mistakes)

0

There are 0 best solutions below