如何确定性地从X/Y坐标生成伪随机模式?

Hen*_*iam 5 java hash deterministic seed coordinates

我正在写一个着色器,它偶尔会在2D地图上产生一个亮点.("闪光"只是一个颜色较亮的像素.)我希望闪闪发光的块随机均匀地分布在(无限)平面上,但我希望闪闪发光是基于X和Y坐标的确定性.我尝试从坐标创建种子并Random从该种子创建Java ,但到目前为止,我的尝试导致了可识别的模式.此功能将被频繁调用(数百万次),因此性能至关重要.

我首先尝试模仿我的hashCode()实现,它使用素数乘数来避免冲突.这导致地图上出现明显的伤口,其中一系列点共享相同的种子.

然后,我尝试通过连接坐标来创建种子,如下所示:

long seed = ((long) x << 32) | (long) y;
Random rand = new Random(seed);
Run Code Online (Sandbox Code Playgroud)

这似乎也导致了图案化数据,尽管模式并不那么明显.选定的坐标以线条显示,根本不均匀分布.

我避免使用MD5或其他加密哈希算法,因为我害怕性能影响.

tra*_*god 2

中实现的线性同余发生器具有java.util.Random对于任何选择都可重复的优点SEED。鉴于这些声明,

private static final int SEED = 42;
private static final int N = 128;
private static final int MAX_X = 1024;
private static final int MAX_Y = 1024;
private final Random rnd = new Random(SEED);
private final List<SparklePoint> list = new ArrayList<SparklePoint>(N);
Run Code Online (Sandbox Code Playgroud)

N您可以初始化矩形中随机选择的点的(可重复)列表,(0, 0, MAX_X, MAX_Y)如下所示:

public void init(int seed) {
    for (int i = 0; i < N; i++) {
        int x = rnd.nextInt(MAX_X);
        int y = rnd.nextInt(MAX_Y);
        list.add(new SparklePoint(x, y));
    }
}
Run Code Online (Sandbox Code Playgroud)

给每个点 a 可能会很方便,Timer其周期是从相同的序列中选择的:

private class SparklePoint implements ActionListener {

    private static final int MAX_DELAY = 1000;
    private final Point p;
    private final Timer t;
    private boolean bright;

    public SparklePoint(int x, int y) {
        p = new Point(x, y);
        t = new Timer(rnd.nextInt(MAX_DELAY), this);
        t.setRepeats(false);
        t.start();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        t.stop();
        if (bright) {
            // darken p
        } else {
            // brighten p
        }
        bright = !bright;
        t.setDelay(rnd.nextInt(MAX_DELAY));
        t.start();
    }
}
Run Code Online (Sandbox Code Playgroud)