Domanda

IV'e lavorava su uno script Perlin ma ha avuto problemi con la creazione di semplici valori casuali pseudo.

Devo essere in grado di creare un valore di seme da una coordinata XY ma X + Y ha problemi evidenti con valori ricorrenti.Inoltre vanno in uno spazio negativo, quindi x ^ y non funziona.

Scusa se questo è già stato risposto da qualche altra parte, ma non ho capito o non riuscivo a trovarlo.

È stato utile?

Soluzione

È necessario definire meglio il problema per ottenere una risposta ottimale.

Se i tuoi valori X e Y sono relativamente piccoli, potresti inserirli nelle porzioni elevate e basse di un intero (è il seme nella tua lingua un numero intero), ad es.Per una piattaforma a 32 bit:

int seed= x << 16 + y;

Se il valore del seme non è permesso di essere negativo (non ho capito appieno cosa intendevi per "spazio negativo" nella tua domanda, sia che ti riferisca alla geografia o al valore del seme), puoi prendere il valore assolutodel seme.

Se si intendeva che le coordinate possano avere valori negativi, la tua migliore linea d'azione dipende dal fatto che tu voglia lo stesso seme per una coordinata e per il suo inverso.

Altri suggerimenti

Vuoi assicurare un numero casuale ripetibile a ciascuna X, Y pair?

L'utilizzo di una combinazione di funzionalità lineare o in generale della X, Y come seme darà artefatti nella distribuzione (almeno se non si utilizza una funzione molto complessa). Prova con questo, ho lo stesso problema a cui ha funzionato per me

//seeded random for JS - integer
function irnd2()
{
    a=1664525;
    c=1013904223;
    m=4294967296;
    rnd2.r=(rnd2.r*a+c)%m;
    return rnd2.r;
}

//seeded random for JS - double [0,1]
function rnd2()
{
    a=1664525;
    c=1013904223;
    m=4294967296;
    rnd2.r=(rnd2.r*a+c)%m;
    return rnd2.r/m;
}


rnd2.r=192837463;

//seed function
function seed2(s)
{
    s=s>0?s:-s;
    rnd2.r=192837463^s;
}

//my smart seed from 2 integer
function myseed(x,y)
{
seed2(x);//x is integer
var sx=irnd2();//sx is integer
seed2(y);//y is integer
var sy=irnd2();//sy is integer
seed2(sx^sy);//using binary xor you won't lose information 
}
.

Per usarlo:

myseed(x,y);
irnd2();
.

In questo modo è possibile ottenere una buona sequenza casuale non correlata.

Lo uso in JS ma dovrebbe funzionare anche in altre lingue che suppongono l'argomento del seme e il valore restituito di RND è un numero intero.

Prendi il valore assoluto di x e y prima;Quindi x^y funzionerà bene.Uno dei modi più semplici per creare una fonte pseudo-casuale è con il tempo.Potresti provare a moltiplicare x^y tramite il tempo di sistema corrente;Questo metodo ha una possibilità estremamente bassa di generare valori di semi ricorrenti.

Se conosci la gamma di valori che hai, potresti semplicemente lanciare X e Y come stringhe imbottite con zeri, aggiungi le due stringhe, quindi eseguire la stringa risultante attraverso una funzione hash.

in c #, adattato e migliorato dalla risposta di Alexroat.Basta impostare Random.seed = MyUtils.GetSeedXY(x, y) e stai bene per andare.

public static class MyUtils
{
    static int seed2(int _s)
    {
        var s = 192837463 ^ System.Math.Abs(_s);
        var a = 1664525;
        var c = 1013904223;
        var m = 4294967296;
        return (int) ((s * a + c) % m);
    }

    public static int GetSeedXY(int x, int y)
    {
        int sx = seed2(x * 1947);
        int sy = seed2(y * 2904);
        return seed2(sx ^ sy);
    }
}
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top