Diamond-Square Random Terran Xors3D Part 1

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

tft

Betreff: Diamond-Square Random Terran Xors3D Part 1

BeitragSa, Nov 13, 2010 22:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo...

im zuge meines momentanen Projectes habe ich mich mit obigen Thema befassen müssen. Nach etlichen vergeblichen Versuchen im Internet etwas auf Deutsch zu finden. Habe ich mich hingesetzt und versucht die Sache für mich irgendwie verständlich zu Visualisieren.

Die für 2D ist dabei rausgekommen.

Code: [AUSKLAPPEN]


;
; Diamond-Square Random Terran 001
;

Global AppName$=      "Diamond-Square Random Terran"

Include "..\..\userlibs\blitzsys.bb"
Include "..\..\userlibs\Xors3D.bb"

Include "include\_xKey_.bb"

If DLLBlitzSysInitialise() = False Then RuntimeError("Blitzsys.dll not found")
If DLLFindWindow(AppName$)<>0 : RuntimeError("Aplication is runing ("+AppName$+")") : EndIf

; ----------------------------------------------------------------------

SeedRnd(MilliSecs())
WinScreenX#=DLLDesktopWidth()
WinScreenY#=DLLDesktopHeight()
Global ScreenX=1600
Global ScreenY=800
WinMode=False ; Windowed
;WinMode=True  ; FullScreen

; ----------------------------------------------------------------------

xGraphics3D(ScreenX,ScreenY,32,WinMode,True)
xSetBuffer(xBackBuffer())

xAppTitle AppName$

Delay 1
If WinMode=False
   hWnd = DLLFindWindow(AppName$)
   succ = DLLSetWindowPos(hWnd,HWND_TOPMOST,(WinScreenX#/2)-(Screenx/2),(WinScreenY#/2)-(Screeny/2),ScreenX,ScreenY,SWP_NOSIZE )
EndIf

; ----------------------------------------------------------------------

; Das Raster wird inizialisiert, di kann bei start 3 - 2^x betragen
; 9 erzieht gute Ergebnisse

di=7

; Die maximale höhe in Y

mr=256


Dim x(di)
Dim x1(di)
For i=0 To di
   x(i)=Rand(mr)
Next

; ----------------------------------------------------------------------

Repeat

   xCls
   
   If xWinMessage("WM_CLOSE") Then Ex=1   ; Close Botton
   If xKeyHit(1) Then Ex=1               ; ECS
   If xKeyHit(2)                     ; Taste 1 , Start new
      di=9
      Dim x(di)
      Dim x1(di)
      For i=0 To di
         x(i)=Rand(mr)
      Next
   EndIf
      
   If xMouseHit(2)
      
      ; Die höhen Daten werden kopiert
      Dim x1(di)
      For i=1 To di
         x1(i)=x(i)
      Next
      
      ; Das Feld wird erweitert
      di=di+(di-1)
      Dim x(di)
      
      ; Die Alten Feld Daten werden Kopiert
      do=1
      i1=1
      For i=1 To di
         If do=i
            do=do+2
            x(i)=x1(i1)
            i1=i1+1
         Else
         EndIf
      Next

      ; Aus den Höhen Daten des Vorherigen und nachkommenden Punktes
      ; wird ein züfälliger Zwischen wert gebildet.
      do=1
      i1=1
      For i=1 To di
         If do=i ; Die forherigen Raster punkte behalten
            do=do+2
         Else ; Die Zwischen Punkte berechnen

            If x(i-1)<=x(i+1)
               x(i)=x(i-1)+Rand(Abs(x(i-1)-x(i+1)))
            Else
               x(i)=x(i+1)+Rand(Abs(x(i-1)-x(i+1)))
            EndIf
            
         EndIf
      Next

   EndIf

   ; Wasser Linie
   xColor($00,$00,$ff)
   xRect(1,ScreenY-100-(mr/2),ScreenX-1,mr/2,1)
   
   ; Raster punkte
   raster_x#=(ScreenX-20)/(di-1.0)
   xColor($ff,$ff,$ff)
   
   For i= 1 To di-1
   
      ;xRect(10+((i-1)*raster_x),ScreenY-100-x(i),2,2,0)
      xLine(10+((i-1)*raster_x),ScreenY-100-x(i),10+((i)*raster_x),ScreenY-100-x(i+1))

   Next

   ; Text Ausgabe
   
   xColor($0,$0,$0)
   xText(ScreenX/2+1,11,"Press rigt mouse botton to generate next calc",1)
   xColor($0,$ff,$ff)
   xText(ScreenX/2,10,"Press rigt mouse botton to generate next calc",1)

   xColor($0,$0,$0)
   xText(11,11,"Points = "+Str(di))
   xColor($0,$ff,$ff)
   xText(10,10,"Points = "+Str(di))
   
   xFlip()

Until Ex=1

End


Das Bild zeigt einen Start mit 9 Punkten.

user posted image

Und dieses wie es mit 4096 aussieht.

user posted image


Der Nächte Teil wird die sache in 3D erzeugen.

Gruss TFT
  • Zuletzt bearbeitet von tft am So, Nov 14, 2010 19:39, insgesamt einmal bearbeitet

Eingeproggt

BeitragSo, Nov 14, 2010 0:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Nimmts mir jemand übel, wenn ich das mal schnell nach "normales BlitzBasic" übersetze, ohne BlitzSys und XOrs? So dass es jeder ausführen kann?
Hoffe nicht, weil das tat ich grad:

BlitzBasic: [AUSKLAPPEN]
; 
; Diamond-Square Random Terrain 001
;

Global AppName$= "Diamond-Square Random Terrain"

; ----------------------------------------------------------------------

SeedRnd(MilliSecs())
Global ScreenX=1600
Global ScreenY=800
WinMode=False ; Windowed
;WinMode=True ; FullScreen

; ----------------------------------------------------------------------

Graphics3D(ScreenX,ScreenY,32,WinMode)
SetBuffer(BackBuffer())

AppTitle AppName$

Global timer=CreateTimer(50)


; ----------------------------------------------------------------------

; Das Raster wird inizialisiert, di kann bei start 3 - 2^x betragen
; 9 erzieht gute Ergebnisse

di=7

; Die maximale höhe in Y

mr=256


Dim x(di)
Dim x1(di)
For i=0 To di
x(i)=Rand(mr)
Next

; ----------------------------------------------------------------------

Repeat

Cls

If KeyHit(1) Then Ex=1 ; ECS
If KeyHit(2) Then ; Taste 1 , Start new
di=9
Dim x(di)
Dim x1(di)
For i=0 To di
x(i)=Rand(mr)
Next
EndIf

If MouseHit(2) Then

; Die höhen Daten werden kopiert
Dim x1(di)
For i=1 To di
x1(i)=x(i)
Next

; Das Feld wird erweitert
di=di+(di-1)
Dim x(di)

; Die Alten Feld Daten werden Kopiert
do=1
i1=1
For i=1 To di
If do=i
do=do+2
x(i)=x1(i1)
i1=i1+1
Else
EndIf
Next

; Aus den Höhen Daten des Vorherigen und nachkommenden Punktes
; wird ein züfälliger Zwischen wert gebildet.
do=1
i1=1
For i=1 To di
If do=i ; Die forherigen Raster punkte behalten
do=do+2
Else ; Die Zwischen Punkte berechnen

If x(i-1)<=x(i+1)
x(i)=x(i-1)+Rand(Abs(x(i-1)-x(i+1)))
Else
x(i)=x(i+1)+Rand(Abs(x(i-1)-x(i+1)))
EndIf

EndIf
Next

EndIf

; Wasser Linie
Color($00,$00,$ff)
Rect(1,ScreenY-100-(mr/2),ScreenX-1,mr/2,1)

; Raster punkte
raster_x#=(ScreenX-20)/(di-1.0)
Color($ff,$ff,$ff)

For i= 1 To di-1

;xRect(10+((i-1)*raster_x),ScreenY-100-x(i),2,2,0)
Line(10+((i-1)*raster_x),ScreenY-100-x(i),10+((i)*raster_x),ScreenY-100-x(i+1))

Next

; Text Ausgabe

Color($0,$0,$0)
Text(ScreenX/2+1,11,"Press rigt mouse botton to generate next calc",1)
Color($0,$ff,$ff)
Text(ScreenX/2,10,"Press rigt mouse botton to generate next calc",1)

Color($0,$0,$0)
Text(11,11,"Points = "+Str(di))
Color($0,$ff,$ff)
Text(10,10,"Points = "+Str(di))

Flip(0)
WaitTimer timer

Until Ex=1

End
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9

tft

BeitragSo, Nov 14, 2010 2:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

da es so einfach ist ..... habe ich jetzt darauf verzichtet. Geht also in ordnung. Smile

Gruss TFT
TFT
https://www.sourcemagic.ch
Monkey,HTML5,CSS3,W 10 64 Bit, 32 GB Ram, GTX Titan, W8 ist Müll !!!!!!

aMul

Sieger des Minimalist Compo 01/13

BeitragSo, Nov 14, 2010 13:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Ein interessanter Code, mit wirklich sehenswertem Ergebnis, wie ich finde.
Hätte nicht gedacht, das man so einfach ein größtenteils vollkommen Spiele-taugliches Terrain erstellen kann(zugegeben, hatte ich mich damit auch noch nie so wirklich beschäftigt.)
Ich bedanke mich fürs veröffentlichen, wenn ich dazu Zeit finde, muss ich unbedingt mal Testen, wie gut sich der Algo auf meinen Versuch an einem Hexagonalen Terrain, oder wie man das nennen will, anwenden lässt.

Ansonsten muss ich zugeben, dass ich deinen Code ein bisschen unübersichtlich finde, was Variablen-Namen und so angeht, und ich glaube auch, dass man die For-Schleifen noch optimaler schreiben könnte.
Aber da es ja "nur ein Test" war, und zumindest für mich der Code(dank der Kommentare Smile ) ohne Probleme verständlich war, lass ich das mal durchgehen. Wink

Nur eine kleine Frage, kann man
BlitzBasic: [AUSKLAPPEN]
If x(i-1)<=x(i+1) 
x(i)=x(i-1)+Rand(Abs(x(i-1)-x(i+1)))
Else
x(i)=x(i+1)+Rand(Abs(x(i-1)-x(i+1)))
EndIf

nicht auch einfach als
BlitzBasic: [AUSKLAPPEN]
x(i)=Rand(x(i-1), x(i+1))

schreiben?
Panic Pong - ultimate action mashup of Pong and Breakout <= aktives Spiele-Projekt, Downloads mit vielen bunten Farben!
advASCIIdraw - the advanced ASCII art program <= aktives nicht-Spiele-Projekt, must-have für ASCII/roguelike/dungeon-crawler fans!
Alter BB-Kram: ThroughTheAsteroidBelt - mit Quelltext! | RGB-Palette in 32²-Textur / Farbige Beleuchtung mit Dot3 | Stereoskopie in Blitz3D | Teleport-Animation Screensaver

tft

BeitragSo, Nov 14, 2010 15:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

bei mir funktioniert Rand() nicht richtig wenn ich Negative Zahlen bei Max und Positive Zahlen bei Min habe.

Gruss TFT
TFT
https://www.sourcemagic.ch
Monkey,HTML5,CSS3,W 10 64 Bit, 32 GB Ram, GTX Titan, W8 ist Müll !!!!!!

Noobody

BeitragSo, Nov 14, 2010 16:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Na sowas. Aber pssssst Wink

Noch ein paar Verbesserungsvorschläge für deine Version:
- Für so etwas kleines braucht es nicht unbedingt Xors3D. Damit sich ein Normaluser deinen Code aber anschauen kann, wird er sich eher nicht noch die ganzen Userlibs nachinstallieren. Also am besten nur mit nativem B3D arbeiten, damit man den Code in die IDE reinkopieren und direkt starten kann.
- Dein Algorithmus erzeugt zwar schöne Klippen, aber es scheint nicht wirklich Diamond Square zu sein. Wenn du einen neuen Zwischenpunkt berechnest, beziehst du nur einen der beiden Punkte nebenan mit ein, bevor du den Zufallswert dazuaddierst. Für Diamond Square aber musst du beide Nachbarpunkte nehmen, den Mittelwert berechnen und erst dann die Zufallszahl hinzuaddieren.
- Wir mögen Screenshots. Am besten also einfach ein kleines Bild des Programms hinzufügen, damit man ungefähr weiss, um was es sich dabei handelt.
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun

tft

BeitragSo, Nov 14, 2010 19:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

ich beziehe jeweils die nachbar punkte in die Ermittlung mit ein .

Code: [AUSKLAPPEN]


If x(i-1)<=x(i+1)
  x(i)=x(i-1)+Rand(Abs(x(i-1)-x(i+1)))
Else    
  x(i)=x(i+1)+Rand(Abs(x(i-1)-x(i+1)))
EndIf



x(i-1) und x(i+1) sind immer die nachbar Punkte aus deren die diverenz zueinander ermittelt und mit Rand(Abs(x(i-1)-x(i+1))) daraus der neue Höhenwert bestimmt wird. Dieser wird dann zum kleinern von beiden dazu addiert.

Wenn man den Code ausführt kann man sehen wie die neuen Punkte immer zwischen zwei bestehenden erzeugt wird.

Was das Arbeiten mit Xors3D anbelangt. So ist es zum einen Werbung ..... zum anderen Tempo und nicht zuletzt ....... dadurch schauen sich die User den Code genauer an. Weil sie ihn nicht einfach Kopieren sondern durchgehen müssen.

Aber die Inlines die nicht wirklich von nöten sind werde ich zukünftig weg lassen.

Gruss TFT

PS: Zwei Bilder nachgereicht Smile
TFT
https://www.sourcemagic.ch
Monkey,HTML5,CSS3,W 10 64 Bit, 32 GB Ram, GTX Titan, W8 ist Müll !!!!!!

tft

BeitragSo, Nov 14, 2010 20:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

und so kann es in 3D aussehen .....


http://www.optima-code.ch/gfx/DS3.wmv

gruss TFT
TFT
https://www.sourcemagic.ch
Monkey,HTML5,CSS3,W 10 64 Bit, 32 GB Ram, GTX Titan, W8 ist Müll !!!!!!
  • Zuletzt bearbeitet von tft am So, Nov 14, 2010 21:43, insgesamt einmal bearbeitet

Noobody

BeitragSo, Nov 14, 2010 21:29
Antworten mit Zitat
Benutzer-Profile anzeigen
tft hat Folgendes geschrieben:
ich beziehe jeweils die nachbar punkte in die Ermittlung mit ein .

Ja, du tust es - aber nicht in Diamond Square-Manier Razz

Wie gesagt, du müsstest beide (oder all vier im 3D-Fall) Nachbarpunkte nehmen, den Mittelwert berechnen, dazu einen kleinen Zufallswert addieren und das als Wert für den Zwischenpunkt nehmen.
So wie du es jetzt machst, gibt es zwar auch hübsche Bilder, aber halt total andere wie Diamond Square.
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun

tft

BeitragSo, Nov 14, 2010 21:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,,

wie soll ich 4 punkte berücksichtigen in 2 D .... in 3 D weis ich wies geht.

Gruss TFT
TFT
https://www.sourcemagic.ch
Monkey,HTML5,CSS3,W 10 64 Bit, 32 GB Ram, GTX Titan, W8 ist Müll !!!!!!

tft

BeitragSo, Nov 14, 2010 22:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

Noobody@

habe deinen Text jetz zum 5. mal durch gelesen .... und jetzt gehts mir erst auf was du meinst. Der Mittel wert beider punkte und dann einen Random Wert dazu addieren. Wobei der Random höchsten 1/4 der diferenze beträgt.

Das würde die sache erheblich flacher und nicht so schroff gestalten.

Gruss TFT
TFT
https://www.sourcemagic.ch
Monkey,HTML5,CSS3,W 10 64 Bit, 32 GB Ram, GTX Titan, W8 ist Müll !!!!!!

tft

BeitragMo, Nov 15, 2010 19:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

nachdem ich mit dem ergebniss der Rutine noch nicht ganz zufriden war. Habe ich mich hingestzt und den Algo überarbeitet.

Ersetzt bitte diesen Teil ....

Code: [AUSKLAPPEN]



If x(i-1)<=x(i+1)
 x(i)=x(i-1)+Rand(Abs(x(i-1)-x(i+1)))
Else
 x(i)=x(i+1)+Rand(Abs(x(i-1)-x(i+1)))
EndIf



durch dehn hir ....

Code: [AUSKLAPPEN]


h#=0.9
div#=Abs(x(i-1)-x(i+1))
cop#=div/2.0
coi#=cop*h
col#=Rnd(-coi,coi)

If x(i-1)<=x(i+1)
 x(i)=x(i-1)+cop+col
Else
 x(i)=x(i+1)+cop+col
EndIf



Gruss TFT
TFT
https://www.sourcemagic.ch
Monkey,HTML5,CSS3,W 10 64 Bit, 32 GB Ram, GTX Titan, W8 ist Müll !!!!!!

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group