我正在尝试创建的是高分辨率元球。这是我的算法:
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 类非常简单,它只是一个从屏幕反弹的球:
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));
}
}
问题是嵌套循环中有太多的迭代,它会导致严重的冻结。我想不出其他方法来检查从屏幕的每个像素到所有斑点的中心点的距离,因此,高分辨率图片和大量斑点使它成为幻灯片。另外我知道将所有内容转换为 BufferedImage 并不是一个完美的主意,但我不知道将光栅转换为图形对象的其他方法。提前感谢您的帮助)(编辑:getSum() 找到所有 blob 的所有距离的总和,将其映射到颜色范围,并将其限制为 255 这个函数当然不是问题,但理解起来有点复杂,这就是为什么我没有包括它)(编辑2:感谢@ThatOtherGuy,现在这种方式更加优化,但可能还有其他一些错误)