Page 1 of 1

Black Hole simulation at the approximation

Posted: Sat Sep 13, 2025 10:04 am
by threedslider
Hi all

I share you a nice Black Hole simulation at the approximation :D

Here the code :

Code: Select all

EnableExplicit

#Width  = 800
#Height = 600

Structure Particle
  angle.f
  radius.f
  x.f
  y.f
  z.f
EndStructure

Global NewList Particles.Particle()

Procedure InitParticles(count)
  Protected i
  For i = 0 To count
    AddElement(Particles())
    Particles()\angle = Random(360)
    Particles()\radius = 1.5 + Random(100) / 50.0
    Particles()\x = Particles()\radius * Cos(Radian(Particles()\angle))
    Particles()\y = 0
    Particles()\z = Particles()\radius * Sin(Radian(Particles()\angle))
  Next
EndProcedure

Procedure InitGL()
  glEnable_(#GL_DEPTH_TEST)
  glEnable_(#GL_POINT_SMOOTH)
  glPointSize_(3.0)
EndProcedure

Procedure DrawSphere(radius.f, latRes.i = 16, lonRes.i = 16)
  Protected i, j
  Protected theta1.f, theta2.f
  Protected phi1.f, phi2.f
  Protected x1.f, y1.f, z1.f
  Protected x2.f, y2.f, z2.f

  For i = 0 To latRes - 1
    theta1 = i * #PI / latRes
    theta2 = (i + 1) * #PI / latRes

    glBegin_(#GL_TRIANGLE_STRIP)
    For j = 0 To lonRes
      phi1 = j * 2 * #PI / lonRes

      x1 = radius * Sin(theta1) * Cos(phi1)
      y1 = radius * Cos(theta1)
      z1 = radius * Sin(theta1) * Sin(phi1)

      x2 = radius * Sin(theta2) * Cos(phi1)
      y2 = radius * Cos(theta2)
      z2 = radius * Sin(theta2) * Sin(phi1)

      glVertex3f_(x1, y1, z1)
      glVertex3f_(x2, y2, z2)
    Next
    glEnd_()
  Next
EndProcedure

Procedure RenderScene()
  glViewport_(0, 0, #Width, #Height)
  glMatrixMode_(#GL_PROJECTION)
  glLoadIdentity_()
  gluPerspective_(45.0, #Width / #Height, 0.1, 100.0)
  glTranslatef_(0.0, 0.0, -1.0)

  glMatrixMode_(#GL_MODELVIEW)
  glLoadIdentity_()

  glClearColor_(0.0, 0.0, 0.0, 1.0)
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)

  gluLookAt_(0, 2, 6, 0, 0, 0, 0, 1, 0)

  ; Central black hole
  glPushMatrix_()
  glColor3f_(0.0, 0.0, 0.0)
  DrawSphere(1.5, 20, 20)
  glPopMatrix_()

  ; violet particles (horizon)
  glBegin_(#GL_POINTS)
  glColor3f_(1.0, 0.0, 1.0) ; violet
 ForEach Particles()
  ; Update for angle in rotation
  Particles()\angle + 0.5
  If Particles()\angle > 360
    Particles()\angle = 0
  EndIf

  ; Coordinates in a circle around the black hole
  Particles()\x = Particles()\radius * Cos(Radian(Particles()\angle))
  Particles()\z = Particles()\radius * Sin(Radian(Particles()\angle))
  
  ; === Manual Gravitational Warp ===
  Define strength.f = 0.4      ; Intensity of deformation
  Define falloff.f  = 0.9      ; Bigger = more spread out
  Particles()\y = strength * Exp(  -Pow(Particles()\z, 2) / falloff )
  
 
  ; Show particle
  glVertex3f_(Particles()\x, Particles()\y, Particles()\z)
Next
  glEnd_()

  FlipBuffers()
EndProcedure

; === MAIN ===

InitKeyboard()

; Creates a true cross-platform OpenGL window
If OpenWindow(0, 0, 0, #Width/DesktopResolutionX(), #Height/DesktopResolutionY(), "Black Hole Simulation", #PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(0), 0, 0, #Width, #Height, 0, 0, 0)
  SetFrameRate(60)
  InitGL()
  InitParticles(3000)

  Repeat
    RenderScene()
    ExamineKeyboard()
    If KeyboardPushed(#PB_Key_Escape)
      Break
    EndIf    
  ForEver
EndIf
Happy coding !

Re: Black Hole simulation at the approximation

Posted: Sat Sep 13, 2025 2:01 pm
by moulder61
@threedslider

Apart from InitSprite() missing, I'm just getting a blank window. :cry:

PB 6.21 Linux - x64

Moulder.

Re: Black Hole simulation at the approximation

Posted: Sat Sep 13, 2025 4:33 pm
by Skipper
Same here, on OSX x64

Re: Black Hole simulation at the approximation

Posted: Sat Sep 13, 2025 4:42 pm
by miso
On windows x64 it worked fine. Looks cool.

Re: Black Hole simulation at the approximation

Posted: Sat Sep 13, 2025 5:34 pm
by threedslider
moulder61 wrote: Sat Sep 13, 2025 2:01 pm @threedslider

Apart from InitSprite() missing, I'm just getting a blank window. :cry:

PB 6.21 Linux - x64

Moulder.
OK, I have fixed there and see my last code :D

Code: Select all

EnableExplicit

#Width  = 800
#Height = 600

Structure Particle
  angle.f
  radius.f
  x.f
  y.f
  z.f
EndStructure

Global NewList Particles.Particle()

Procedure InitParticles(count)
  Protected i
  For i = 0 To count
    AddElement(Particles())
    Particles()\angle = Random(360)
    Particles()\radius = 1.5 + Random(100) / 50.0
    Particles()\x = Particles()\radius * Cos(Radian(Particles()\angle))
    Particles()\y = 0
    Particles()\z = Particles()\radius * Sin(Radian(Particles()\angle))
  Next
EndProcedure

Procedure InitGL()
  glEnable_(#GL_DEPTH_TEST)
  glEnable_(#GL_POINT_SMOOTH)
  glPointSize_(3.0)
EndProcedure

Procedure DrawSphere(radius.f, latRes.i = 16, lonRes.i = 16)
  Protected i, j
  Protected theta1.f, theta2.f
  Protected phi1.f, phi2.f
  Protected x1.f, y1.f, z1.f
  Protected x2.f, y2.f, z2.f

  For i = 0 To latRes - 1
    theta1 = i * #PI / latRes
    theta2 = (i + 1) * #PI / latRes

    glBegin_(#GL_TRIANGLE_STRIP)
    For j = 0 To lonRes
      phi1 = j * 2 * #PI / lonRes

      x1 = radius * Sin(theta1) * Cos(phi1)
      y1 = radius * Cos(theta1)
      z1 = radius * Sin(theta1) * Sin(phi1)

      x2 = radius * Sin(theta2) * Cos(phi1)
      y2 = radius * Cos(theta2)
      z2 = radius * Sin(theta2) * Sin(phi1)

      glVertex3f_(x1, y1, z1)
      glVertex3f_(x2, y2, z2)
    Next
    glEnd_()
  Next
EndProcedure

Procedure RenderScene()
  glViewport_(0, 0, #Width, #Height)
  glMatrixMode_(#GL_PROJECTION)
  glLoadIdentity_()
  gluPerspective_(45.0, #Width / #Height, 0.1, 100.0)
  glTranslatef_(0.0, 0.0, -1.0)

  glMatrixMode_(#GL_MODELVIEW)
  glLoadIdentity_()

  glClearColor_(0.0, 0.0, 0.0, 1.0)
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)

  gluLookAt_(0, 2, 6, 0, 0, 0, 0, 1, 0)

  ; Central black hole
  glPushMatrix_()
  glColor3f_(0.0, 0.0, 0.0)
  DrawSphere(1.5, 20, 20)
  glPopMatrix_()

  ; violet particles (horizon)
  glBegin_(#GL_POINTS)
  glColor3f_(1.0, 0.0, 1.0) ; violet
 ForEach Particles()
  ; Update for angle in rotation
  Particles()\angle + 0.5
  If Particles()\angle > 360
    Particles()\angle = 0
  EndIf

  ; Coordinates in a circle around the black hole
  Particles()\x = Particles()\radius * Cos(Radian(Particles()\angle))
  Particles()\z = Particles()\radius * Sin(Radian(Particles()\angle))
  
  ; === Manual Gravitational Warp ===
  Define strength.f = 0.4      ; Intensity of deformation
  Define falloff.f  = 0.9      ; Bigger = more spread out
  Particles()\y = strength * Exp(  -Pow(Particles()\z, 2) / falloff )
  
 
  ; Show particle
  glVertex3f_(Particles()\x, Particles()\y, Particles()\z)
Next
  glEnd_()

  FlipBuffers()
EndProcedure

; === MAIN ===

InitSprite()
InitKeyboard()
Define Event
; Creates a true cross-platform OpenGL window
If OpenWindow(0, 0, 0, #Width/DesktopResolutionX(), #Height/DesktopResolutionY(), "Black Hole Simulation", #PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(0), 0, 0, #Width, #Height, 0, 0, 0)
  SetFrameRate(60)
  InitGL()
  InitParticles(3000)

  Repeat
      Repeat
         Event = WindowEvent()
         If event = #PB_Event_CloseWindow : End : EndIf
       Until event = 0
       
    RenderScene()
    ExamineKeyboard()
       
  Until KeyboardPushed(#PB_Key_Escape)
EndIf
Enjoy !

Re: Black Hole simulation at the approximation

Posted: Sat Sep 13, 2025 5:48 pm
by threedslider
Skipper wrote: Sat Sep 13, 2025 4:33 pm Same here, on OSX x64
Now it works for you ?

Re: Black Hole simulation at the approximation

Posted: Sat Sep 13, 2025 5:49 pm
by threedslider
miso wrote: Sat Sep 13, 2025 4:42 pm On windows x64 it worked fine. Looks cool.
Thanks for testing :D

Re: Black Hole simulation at the approximation

Posted: Sat Sep 13, 2025 5:54 pm
by threedslider
An improvement as well :D

the code :

Code: Select all

EnableExplicit

#Width  = 800
#Height = 600

Structure Particle
  angle.f
  radius.f
  x.f
  y.f
  z.f
EndStructure

Global NewList Particles.Particle()

Procedure InitParticles(count)
  Protected i
  For i = 0 To count
    AddElement(Particles())
    Particles()\angle = Random(360)
    Particles()\radius = 1.5 + Random(100) / 50.0
    Particles()\x = Particles()\radius * Cos(Radian(Particles()\angle))
    Particles()\y = 0
    Particles()\z = Particles()\radius * Sin(Radian(Particles()\angle))
  Next
EndProcedure

Procedure InitGL()
  glEnable_(#GL_DEPTH_TEST)
  glEnable_(#GL_POINT_SMOOTH)
  glPointSize_(3.0)
EndProcedure

Procedure DrawSphere(radius.f, latRes.i = 16, lonRes.i = 16)
  Protected i, j
  Protected theta1.f, theta2.f
  Protected phi1.f, phi2.f
  Protected x1.f, y1.f, z1.f
  Protected x2.f, y2.f, z2.f

  For i = 0 To latRes - 1
    theta1 = i * #PI / latRes
    theta2 = (i + 1) * #PI / latRes

    glBegin_(#GL_TRIANGLE_STRIP)
    For j = 0 To lonRes
      phi1 = j * 2 * #PI / lonRes

      x1 = radius * Sin(theta1) * Cos(phi1)
      y1 = radius * Cos(theta1)
      z1 = radius * Sin(theta1) * Sin(phi1)

      x2 = radius * Sin(theta2) * Cos(phi1)
      y2 = radius * Cos(theta2)
      z2 = radius * Sin(theta2) * Sin(phi1)

      glVertex3f_(x1, y1, z1)
      glVertex3f_(x2, y2, z2)
    Next
    glEnd_()
  Next
EndProcedure

Procedure RenderScene()
  glViewport_(0, 0, #Width, #Height)
  glMatrixMode_(#GL_PROJECTION)
  glLoadIdentity_()
  gluPerspective_(45.0, #Width / #Height, 0.1, 100.0)
  glTranslatef_(0.0, 0.0, -1.0)

  glMatrixMode_(#GL_MODELVIEW)
  glLoadIdentity_()

  glClearColor_(0.0, 0.0, 0.0, 1.0)
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)

  gluLookAt_(0, 2, 6, 0, 0, 0, 0, 1, 0)

  ; Central black hole
  glPushMatrix_()
  glColor3f_(0.0, 0.0, 0.0)
  DrawSphere(1.5, 20, 20)
  glPopMatrix_()
  
  glEnable_(#GL_BLEND)
  glBlendFunc_(#GL_SRC_ALPHA, #GL_ONE)
  glEnable_(#GL_POINT_SMOOTH)
  glHint_(#GL_POINT_SMOOTH_HINT, #GL_NICEST)
  glPointSize_(2.0)
  
  ; violet particles (horizon)
  glBegin_(#GL_POINTS)
  glColor4f_(1.0, 0.5, 1.0, 0.5) ; clear violet and semi-transparent
 ForEach Particles()
  ; Update for angle in rotation
  Particles()\angle + 0.5
  If Particles()\angle > 360
    Particles()\angle = 0
  EndIf

  ; Coordinates in a circle around the black hole
  Particles()\x = Particles()\radius * Cos(Radian(Particles()\angle))
  Particles()\z = Particles()\radius * Sin(Radian(Particles()\angle))
  
  ; === Manual Gravitational Warp ===
  Define strength.f = 0.4      ; Intensity of deformation
  Define falloff.f  = 0.9      ; Bigger = more spread out
  Particles()\y = strength * Exp(  -Pow(Particles()\z, 2) / falloff )
  
 
  ; Show particle
  glVertex3f_(Particles()\x, Particles()\y, Particles()\z)
Next
  glEnd_()

  FlipBuffers()
EndProcedure

; === MAIN ===

InitSprite()
InitKeyboard()

Define Event

; Creates a true cross-platform OpenGL window
If OpenWindow(0, 0, 0, #Width/DesktopResolutionX(), #Height/DesktopResolutionY(), "Black Hole Simulation", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(0), 0, 0, #Width, #Height, 0, 0, 0)
  SetFrameRate(60)
  InitGL()
  InitParticles(10000)

  Repeat
    Repeat
      Event = WindowEvent()
      If event = #PB_Event_CloseWindow : End : EndIf
    Until event = 0
    
    RenderScene()
    glDisable_(#GL_BLEND)
    ExamineKeyboard()
    Until KeyboardPushed(#PB_Key_Escape)
EndIf
Hope that works for everyone :mrgreen:

Re: Black Hole simulation at the approximation

Posted: Sat Sep 13, 2025 7:33 pm
by minimy
Hey threeslider, very nice! Lost in space? :lol:

Re: Black Hole simulation at the approximation

Posted: Sat Sep 13, 2025 7:57 pm
by moulder61
@threedslider

That's fixed it. Very nice. :D

Moulder.

Re: Black Hole simulation at the approximation

Posted: Sat Sep 13, 2025 9:15 pm
by threedslider
minimy wrote: Sat Sep 13, 2025 7:33 pm Hey threeslider, very nice! Lost in space? :lol:
Interstellar :lol:

Re: Black Hole simulation at the approximation

Posted: Sat Sep 13, 2025 9:15 pm
by threedslider
moulder61 wrote: Sat Sep 13, 2025 7:57 pm @threedslider

That's fixed it. Very nice. :D

Moulder.
Thanks for testing as well :wink: