limits Problem



  • Moin!
    Ich hab da ein kleines Problem dass mir die Breite von __int64 nicht ausreicht. Wär schön wenn jemand vielleicht nen Denkanstoß hätte...

    Alsooooo...
    Ich hab mir
    http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
    vorgenommen und mir ne PerlinNoise-Klasse gebastelt

    und die Zufallszahlen-Funktion sieht bei mir aus wie...

    template <class T>
    T Noise0<T>::NoiseRand (UINT index) const
    {
    	return (1103515245 * (m_dwSeed + index) + 12345) % 0x7fffffff;
    }
    

    So weit so gut. NoiseRand mit dem selben Index aufgerufen gibt auch die selbe Zufallszahl wieder aus.

    Für 2D dann so:

    template <class T>
    T Noise0<T>::NoiseRand (UINT x, UINT y) const
    {
    	DWORD index = x + (UINT_MAX * y);
    	return (1103515245 * (m_dwSeed + index) + 12345) % 0x7fffffff;
    }
    

    Da fällt jetzt vielleicht das UINT_MAX auf...
    Die Koordinaten müssen zum Index umgerechnet werden. Kennt man ja von gewissen anderen Stellen.
    Ist ja auch kein Problem WENN MAN DIE BREITE KENNT.

    Mein Noise ist aber dynamisch berechnet. Breite+Höhe ist nicht festgelegt/begrenzt. Ich werd das auch brauchen um fortlaufend immer wieder eine neue Zeile zu bekommen.

    Den Index-Umrechnungs-Gedanken bis zum 4D-Noise weitergedacht ist die maximale Länge einer jeden Dimension = die 4te Wurzel aus der größten Zahl die ich hinbekomme.
    __int128 will der Compiler irgendwie nicht nehmen (bin noch am recherchieren).
    Bei unsigned __int64 als index, ist die maximale Dimensions-Länge 65535. Das kommt mir ziemlichst zu wenig vor.


  • Mod

    1. Ist das nicht vollkommen egal? Wenn ich den Link richtig verstanden habe, dann willst du doch bloß an jedem Punkt einen anderen Startwert, da ist es doch egal wie groß dein Feld wirklich ist.
    2. Überschlag mal wieviel Speicherplatz du brauchst um ein 65000x65000x65000x65000 Feld zu verwalten. Tipp: Diese Rechnung ist nicht schwer 😉



  • ne is leider nicht egal. Hab da auch schon drüber nachgedacht aber das ginge dann nicht ohne merkwürdige Verschiebungen.

    Komplett das ganze verwalten will ich nicht. Ich will nur nicht dass es sich zu häufig wiederholen würde.
    Wobei mir da grad selbst zweifel aufkommen... Es geht schließlich um die Eckpunkte. die sind dann <m_nWaveLength> voneinander entfernt. Das summiert sich eigentlich auch noch....

    ach ich machs einfach so und schau mal was bei rauskommt.



    1. __int64 und Konsorten würde ich aus Portabilitätsgründen vermeiden. Dann eher sowas wie int64_t aus <stdint.h> (C99) bzw. <cstdint> (C++0x) bzw. <boost/cstdint.hpp> (C++98/03 mit Boost)

    2. Es gibt diverse Klassen für "BigInts", d.h. für Integer mit extremer oder beliebiger Größe

    3. Ich würd den Index anders berechnen, wenn das von der Logik her erlaubt ist. Du numerierst aktuell wie folgt durch:

    Vereinfache UINT_MAX=10

    01 02 03 04 ... 10
    11 12 13 14 ... 20
    .  .            .
    .     .         .
    .        .      .
    91 92 93 94 ...100
    

    Dabei verschenkst du ne ganze Reihe indizes, wenn x viel kleiner als UNINT_MAX bleibt.

    Mein Vorschlag:

    01 02 04 07
    03 05 08
    06 09
    10    ...
    

    Damit wären die Dimensionen in alle Richtungen offen.
    Formel:
    y + (x+y-2)(x+y-1)/2



  • öm....hä?
    wenn ich deine Formel mit x=1 und y=2 fütter krieg ich 2,5 raus.
    Das raff ich grad nicht.



  • sorry verrechnet!
    Es kommt 3 raus.
    aber bei x=2 und y=1 käme auch 3 raus...



  • nein doch nicht! Ich glaub ich halt mich erstmal zurück bevors noch peinlich wird 😃 😃 😃



  • OK habs durchgerechnet. Aber nur kaum schlauer geworden...
    Versteh ich das richtig dass du in deinem Beispiel annimmst dass für y=0 der größte bisher verwendete x-Wert 4 ist? und bei y=1 ist es 3?

    ich hab mal excel mit der Formel gefüttert und ein 10x10 Feld mit Indices produziert.
    Das sieht nicht ganz so gleichmäßig aus wie bei dir:
    hier mal 0/0 bis 4/4

    1  1  2  4  7
    0  1  3  6 10
    0  2  5  9 14
    1  4  8 13 19
    3  7 12 18 25
    

    12 scheint der erste eindeutige Index zu sein.
    Das an sich ist kein Problem. Einfach intern offset draufrechnen.
    Aber ich bin nicht sicher ob ich das richtig verstanden hab. Und dadurch krieg ich die Formel allein nicht 3d-fähig..





  • so sollte das gehen:

    template <class T>
    T Noise0<T>::NoiseRand (UINT x, UINT y) const
    {
    	DWORD index = x + NoiseRand(y);
    	return NoiseRand(index);
    }
    

Log in to reply