Planetenumlaufbahn darstellen

Übersicht BlitzBasic Blitz3D

Neue Antwort erstellen

 

Krischan

Betreff: Planetenumlaufbahn darstellen

BeitragMi, Jan 07, 2009 16:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Für mein Sonnensystem suche ich nach einer relativ simplen Möglichkeit, die Umlaufbahn eines Planeten mittels eines immer 1px breiten 2D Kreises darzustellen, egal wie weit man von der Umlaufbahn entfernt ist. Ich habe schon mit 3D Ringen aus Vertices experimentiert, das Problem ist nur, wenn man zu weit weg ist verschwimmen die Linien bzw. wenn man zu nach dran ist sind sie zu breit, daher am Besten immer 1px breit, egal wie weit weg.

Wie müsste eine Circle/Ellipsenfunktion aussehen, damit ich an Position x,y,z einen 2D-Kreis mit Radius r zeichnen kann? Optional wäre natürlich noch pitch,yaw,roll interessant, für exzentrische Umlaufbahnen. Der Kreis sollte natürlich die Umlaufbahn des Planeten relativ zur Kamera repräsentieren, also müsste ständig dymanisch neu erstellt werden.

Oder habt Ihr eine andere Idee, wie man das schnell und einfach lösen kann?

Hier eine Veranschaulichung, wenn auch dieser Code dafür nicht geeignet ist (ich plotte hier die Vertices eines Cones ohne die Spitze so dass der Eindruck einer 2D Ellipse entsteht):

Code: [AUSKLAPPEN]
Graphics3D 800,600,32,2

camera = CreateCamera()
PositionEntity camera, 0,0,-4

sphere=CreateCone(128)
HideEntity sphere

While Not KeyDown(1)
   
   TurnEntity sphere , 0.5, 0.75, 1
   RenderWorld()
   SPHEREplot(camera, sphere )
   Flip
   
Wend


Function SPHEREplot (camera, entity )
   
   bb=BackBuffer()
   rgb=255*$10000+255*$100+255
   
   s = GetSurface( entity , 1 )
   
   LockBuffer bb
   SetBuffer bb
   
   For v = 128 To CountVertices( s) -1
      TFormPoint VertexX( s, v ) , VertexY( s, v ) , VertexZ( s, v ) , entity , 0
      CameraProject camera , TFormedX(), TFormedY(), TFormedZ()
      
      px%=ProjectedX()
      py%=ProjectedY()
      
      If px>0 And px<800 And py>0 And py<600 Then WritePixelFast px,py,rgb
   Next
   
   UnlockBuffer bb
   
End Function


Der Kreis müsste natürlich mit einer schnellen Funktion in den Puffer gezeichnet werden, so wie hier:

Code: [AUSKLAPPEN]
Graphics 800,600,32,2

; 1. Oval BB
ms=MilliSecs()
Oval 200,100,400,400,0
Text 0,0,"Oval....: "+(MilliSecs()-ms)+"ms"

; 2. Funktion
ms=MilliSecs()
Const density#=1
x_centre=400
y_centre=300
x_diameter=210
y_diameter=210

For a#=0 To 359 Step density#
   x1=x_diameter*Sin(a#)+x_centre
   y1=y_diameter*Cos(a#)+y_centre
   x2=x_diameter*Sin(a#+density)+x_centre
   y2=y_diameter*Cos(a#+density)+y_centre
   
   Color Rand(0,255),Rand(0,255),Rand(0,255)
   
   Line x1,y1,x2,y2
Next

Color 255,255,255
Text 0,15,"Funktion: "+(MilliSecs()-ms)+"ms"

WaitKey

End

Tankbuster

BeitragMi, Jan 07, 2009 16:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Warum erstellst du nicht ein Sprite, mit einer Kreistextur, und skalierst es nach der Entfernung von Spieler-Planet, damit es immer gleichgroß ist? (ich habe es nicht getestet, aber es müsste meiner Meinung nach dann immer gleichgroß sein)

EDIT: Oki, ich bin mir nichtmehr sicher, ob das wirklich eine so gute Idee ist. Immerhin müsste das Sprite dafür extrem groß sein >_<
Twitter
Download Jewel Snake!
Windows|Android
 

Krischan

BeitragMi, Jan 07, 2009 16:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Hmm nur wenn man auf der "äquatorialen Höhe" des Sonnensystems fliegt verschwindet die Linie da auch, ähnlich wie derzeit die Saturnringe. Deshalb die Idee mit den immer 1px grossen Linien, die sind von allen Seiten/Entfernungen gleich gross. Nur... wie?

Hier zur Veranschaulichung:
user posted image
  • Zuletzt bearbeitet von Krischan am Mi, Jan 07, 2009 18:22, insgesamt einmal bearbeitet
 

Krischan

BeitragMi, Jan 07, 2009 16:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich glaube, ich habe was in meinem Archiv gefunden. Der Trick hierbei ist, mittels 3D Funktionen aus Linien einen Ring zu erstellen, dann alle anderen Objekte zu verstecken und das ganze im Wireframe-Modus zu berechnen und dann alle anderen Objekte darüber zu zeichnen. Ist vermutlich schneller als alles was mit Writepixelfast gebastelt werden könnte...

Code: [AUSKLAPPEN]
Graphics3D 800,600,32,2
   SetBuffer BackBuffer()

   SeedRnd MilliSecs()
   fps_timer = CreateTimer(60)
   
   wiref_piv = CreatePivot()
   solid_piv = CreatePivot()
   
   cam = CreateCamera()
   PositionEntity cam,0,2,-5
   
   light = CreateLight()
   
   planet = CreateSphere(16,solid_piv)
   EntityColor planet,0,100,200
   
   For n=1 To 10
      ring = create_ring(100,ring,n, 255,255,255)
   Next
   EntityParent ring,wiref_piv
   
   PointEntity cam,solid_piv
   
   MoveMouse 400,300
   
   ; Main loop
   While Not KeyHit(1)
      ;TurnEntity ring,1,1,1
      
      mxs#=MouseXSpeed()
      mys#=MouseYSpeed()
      RotateEntity cam,EntityPitch(cam)+(mys#/5),EntityYaw(cam)-(mxs#/5),0
      MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
      If KeyDown(200) Then MoveEntity cam,0,0,0.1
      If KeyDown(208) Then MoveEntity cam,0,0,-0.1
      If KeyDown(205) Then MoveEntity cam,0.1,0,0
      If KeyDown(203) Then MoveEntity cam,0.1,0,0
      
      ; Render wireframe objects.
      WireFrame 1
      ShowEntity wiref_piv
      HideEntity solid_piv
      ;PositionEntity wiref_piv,0,0,0,1
      ;PositionEntity solid_piv,0,0,10000,1
      CameraClsMode cam,1,1      
      RenderWorld

      ; Render solid objects.
      WireFrame 0
      HideEntity wiref_piv
      ShowEntity solid_piv
      ;PositionEntity solid_piv,0,0,0,1
      ;PositionEntity wiref_piv,0,0,10000,1
      CameraClsMode cam,0,0      
      RenderWorld
      
      WaitTimer(fps_timer)
      Flip 1
   Wend

   End


;
;
;
;
Function create_ring(segs%,mesh=0,rad#=1,r%=255,g%=255,b%=255)
   
   rstep# = 360.0/segs
   last_ang# = 0
   
   For i = 1 To segs
      new_ang# = last_ang + rstep
      mesh = create_3D_line(mesh, Cos(last_ang)*rad,0,Sin(last_ang)*rad, Cos(new_ang)*rad,0,Sin(new_ang)*rad, r,g,b)
      last_ang = new_ang
   Next
   
   Return mesh

End Function

;
; Adds a 3D line to the specified mesh.
; Note: 3D lines are only properly visible when rendered in wireframe mode!
;
; Params:
; mesh     - Mesh to add 3D line to. If 0, a new mesh is created.
; x0,y0,z0 - Start point of line.
; x1,y2,z1 - End point of line.
; r,g,b    - Line colour.
;
; Returns:
; Handle of mesh the 3D line was added to.
;
Function create_3D_line(mesh,x0#,y0#,z0#,x1#,y1#,z1#,r%=255,g%=255,b%=255)

   If mesh = 0
      mesh = CreateMesh()
      surf = CreateSurface(mesh)
      EntityFX mesh,1+2+16
   Else
      last_surf = CountSurfaces(mesh)
      surf = GetSurface(mesh,last_surf)
      If CountVertices(surf) > 30000 Then surf = CreateSurface(mesh)
   End If

   v0 = AddVertex(surf,x0,y0,z0)
   v1 = AddVertex(surf,x1,y1,z1) 
   v2 = AddVertex(surf,x0,y0,z0) 
   AddTriangle surf,v0,v1,v2
   
   VertexColor surf,v0,r,g,b
   VertexColor surf,v1,r,g,b
   VertexColor surf,v2,r,g,b

   Return mesh

End Function

Neue Antwort erstellen


Übersicht BlitzBasic Blitz3D

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group