Wellenprogramm

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

Noobody

Betreff: Wellenprogramm

BeitragMi, Feb 13, 2008 1:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe mich in letzter Zeit nebenbei ein wenig mit Wellensimulationen beschäftigt.
Da mir jedoch die Wellengleichung viel zu kompliziert war, habe ich eine Annäherung entwickelt, die einigermassen annehmbare Ergebnisse liefert.
Und zwar sehe ich die Wasseroberfläche nur als ein Netz verschiedener träger Punkte, die durch gummibandähnliche Verbindungen verbunden sind.
So drückt ein Gegenstand, der ins das Wasser fällt, nur einen bzw. mehrere Gitterpunkte nach unten, die andere Punkte in der Umgebung nun auch nach unten ziehen.
Sie selbst werden nun aber wieder von den umgebenden Punkten nach oben gezogen, wodurch wellenähnliche Strukturen entstehen.
Lange Rede, kurzer Code:
Code: [AUSKLAPPEN]

Graphics3D 800, 600, 0, 2
SetBuffer BackBuffer()

Const GRIDSIZE# = 2
Const INITIALHEIGHT# = 0
Const WATERSIZE = 100

;Wasser erstellen
Global MotherWater = InitWater()
Dim WaterSpeed#( WATERSIZE*WATERSIZE - 1 )

;Timer
Timer = CreateTimer( 60 )

;Grafikkram
Global Cam = CreateCamera()
PositionEntity Cam, WATERSIZE*GRIDSIZE#/2, 10, WATERSIZE*GRIDSIZE#/2
TurnEntity Cam, 90, 0, 0

Light = CreateLight()
PositionEntity Light, 0, 5, 0

;Hauptschleife
While Not KeyHit( 1 )
   RenderWorld
   
   MoveEntity Cam, KeyDown( 205 ) - KeyDown( 203 ), 0, KeyDown( 200 ) - KeyDown( 208 )
   TurnEntity Cam, MouseYSpeed(), -MouseXSpeed(), 0
   MoveMouse GraphicsWidth()/2, GraphicsHeight()/2
   
   WireFrame MouseDown( 1 )
   
   If MouseHit( 2 ) Then
      CameraPick Cam, GraphicsWidth()/2, GraphicsHeight()/2
      CreateWave( MotherWater, PickedX(), PickedZ(), 10 )
   EndIf
   
   UpdateWaves( MotherWater )
   
   Flip 0
   WaitTimer Timer
Wend

End

Function UpdateWaves( Mesh )
   WaterSurf = GetSurface( Mesh, 1 )
   For Z = 1 To WATERSIZE - 2
      For X = 1 To WATERSIZE - 2
         VertexID = Z*WATERSIZE + X - 1
         CurrentY# = VertexY( WaterSurf, VertexID )
         
         Average# = 0
         For i = Z - 1 To Z + 1
            For t = X - 1 To X + 1
               If Not( i = Z And t = X ) Then
                  If i + t > 0 Then
                     Average# = Average# + VertexY( WaterSurf, i*WATERSIZE + t - 1 )
                  EndIf
               EndIf
            Next
         Next
         Average# = Average#/8
         
         WaterSpeed#( VertexID ) = WaterSpeed#( VertexID ) + ( Average# - CurrentY# )
            
         VertexCoords Watersurf, VertexID, VertexX( WaterSurf, VertexID ), CurrentY + WaterSpeed#( VertexID )/100, VertexZ( WaterSurf, VertexID )
      Next
   Next
   
   UpdateNormals Mesh
End Function

Function CreateWave( Mesh, X#, Z#, Height#, Radius = 0 )
   TFormPoint X#, Height#, Z#, 0, Mesh
   InitX = Int( TFormedZ()/GRIDSIZE# )
   InitZ = Int( TFormedX()/GRIDSIZE# )
   
   WaterSurf = GetSurface( Mesh, 1 )
   
   For X = InitX - Radius To InitX + Radius
      For Z = InitZ - Radius To InitZ + Radius
         Vertex = X*WATERSIZE + Z - 1
         If Not( Vertex < 0 Or Vertex > CountVertices( WaterSurf ) )
            OldX# = VertexX( WaterSurf, Vertex )
            OldZ# = VertexZ( WaterSurf, Vertex )
            VertexCoords WaterSurf, Vertex, OldX#, TFormedY(), OldZ#
         EndIf
      Next
   Next
End Function

Function InitWater()
   WaterMesh = CreateMesh()
   WaterSurf = CreateSurface( WaterMesh )
   
   For Z = 1 To WATERSIZE
      For X = 1 To WATERSIZE
         AddVertex( WaterSurf, X*GRIDSIZE#, INITIALHEIGHT#, Z*GRIDSIZE# )
      Next
   Next
   
   For Z = 1 To WATERSIZE - 1
      For X = 1 To WATERSIZE - 1
         Vertex1 = ( Z - 1 )*WATERSIZE + X - 1
         Vertex2 = ( Z - 1 )*WATERSIZE + X
         Vertex3 = Z*WATERSIZE + X - 1
         Vertex4 = Z*WATERSIZE + X
         AddTriangle( WaterSurf, Vertex1, Vertex3, Vertex2 )
         AddTriangle( WaterSurf, Vertex3, Vertex4, Vertex2 )
      Next
   Next
   
   UpdateNormals WaterMesh
   EntityPickMode WaterMesh, 2
   
   Return WaterMesh
End Function


Erklärung:
Linke Maustaste gedrückt halten für Wireframe, Pfeiltasten und Maus zum Bewegen/Rumgucken und schliesslich rechte Maustaste zum Wellensetzen.

Mein Problem ist nun, dass sich die Wellen, sobald sie am Rand reflektiert werden, gegenseitig aufschaukeln, so dass man Wellen hat, die nach oben und unten in die Unendlichkeit gehen, wenn man das Programm lange genug laufen lässt (probiert es mal aus, dann versteht ihr, was ich meine).
Wie kann man das beheben, falls es überhaupt möglich ist?
Gibt es Alternativen?

MfG
Noobody
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

NightPhoenix

BeitragMi, Feb 13, 2008 11:15
Antworten mit Zitat
Benutzer-Profile anzeigen
also für mich sieht das so aus, als ob du die Wellen zu langsam abbauen lässt. Ihre Energie wird zu lange behalten, dadurch kann sich das ganze bei Kreuzwellen im Wellenberg und Wellental verstärken bzw. abschwächen. Real wird die Amplitude von 2 aufeinander treffenden Wellen addiert. Trifft ein Wellental auf ein Wellenberg mit gleicher Amplitude so eliminieren sie sich. treffen 2 gleiche wie z.b. zwei wellenberge aufeinander dann verdoppelt sich die Größe der Ausgangswelle. Dadurch vielleicht das ewige Aufbauen. Dabei ist es nicht schwer dass sogenannte "stehende Wellen" entstehen, was erklären würde wieso deine Wellen sich irgendwann nicht mehr wirklich bewegen.
Versuch einfach mal den Wellen ihre Energie schneller wegzunehmen, in der Realität hast du das bei Wellen auch auf ihrer scheinbaren Wanderung, bloß dass sie auf dem Meer durch Wind immer wieder Energie zugeführt bekommen und etwas anders aussehen als deine Wellen, die auf dem Meer sind nämlich nach vorne geneigt Wink
Es sieht zwar schick aus muss ich sagen, aber besonders realtimefähig ist das nicht gerade... hatte weniger als 30 FPS ^^ für was brauchst du das?
MfG.

Noobody

BeitragMi, Feb 13, 2008 12:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Eigentlich brauchte ich es für gar nichts, es hatte mich nur interessiert, ob meine Idee überhaupt funktioniert Razz
Auch ist der Code noch überhaupt nicht optimiert, da sind sicher noch einige FPS rauszuholen.
Die Wellen bauen sich beim momentanen Code gar nicht mehr ab, da ich nichts eingebaut habe, um die innere Reibung zu simulieren (irgendwo ein *0.5 sollte schon reichen).
Aber das ist ja gar nicht das Problem.
Es liegt eher darin, dass sich reale Wellen in einem Medium ohne Reibung nie so verhalten würden, wie es die in meinem Programm tuen.
Ich schätze mal, dass es, wie du gesagt hast, daran liegt, dass sich die Wellen nicht gegenseitig eliminieren können.
Aber das einzubauen, dazu fällt mir jetzt grade nichts ein...
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

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group