[Gambas-user] Testing scripter, but found this script to be slow

Benoît Minisini g4mba5 at gmail.com
Mon Jan 11 19:16:29 CET 2021


Le 11/01/2021 à 18:02, Brian G a écrit :
> I have attached for those of you having coffee this morning a quick 
> morning donut.....
> 

Here is a slightly better version.

Tips: IIf() is not optimized by the JIT compiler. Use a normal IF test 
instead.

Regards,

-- 
Benoît Minisini
-------------- next part --------------
#!/usr/bin/gbs3
' Gambas Script File Created 01/10/2021 20:11:31.237
' Original Donut program by Andy Sloane
' https://www.a1k0n.net/2011/07/20/donut-math.html

' Gambas module file

Fast Unsafe

Const theta_spacing As Float = 0.03
Const phi_spacing As Float = 0.01

Const R1 As Float = 1.00
Const R2 As Float = 2.00
Const K2 As Float = 5.0
Private myterm As Stream = File.out
Private screen_width As Float = myterm.term.width
Private screen_height As Float = myterm.term.height

'Calculate K1 based On screen size: the maximum x - distance occurs
'roughly at the edge Of the torus, which Is At x = R1 + R2, z = 0. we
'want that To be displaced 3 / 8 ths Of the width Of the screen, which
'Is 3 / 4 th Of the way From the center To the side Of the screen.
'screen_width * 3 / 8 = K1 * (R1 + R2) / (K2 + 0)
'screen_width * K2 * 3 / (8 * (R1 + R2)) = K1

Private K1 As Float = screen_width * K2 * 1.00 / (9.00 * (R1 + R2))
Private iterations As Long = 0
Public Sub Main()

  Print "Hello world"
  Print "\x1b[2J"
  Dim a, b As Float
  Dim fTimer as Float
  
  Dec screen_height
  
  While True
    fTimer = Timer
    render_frame(a, b)
    a += 0.07
    b += 0.03
    iterations = 0
    fTimer = Timer - fTimer
    Print Format(fTimer, "0.####");"s";
  Wend
End

Public Sub render_frame(a As Float, b As Float)
  'precompute sines And cosines Of A And B
  Dim cosA As Float = Cos(A)
  Dim sinA As Float = Sin(A)
  Dim cosB As Float = Cos(B)
  Dim sinB As Float = Sin(B)
  Dim boutput As New Byte[screen_width, screen_height]
  Dim zbuffer As New Float[screen_width, screen_height]
  Dim sBuffer As String
  
  bOutput.Fill(32)
  
  For theta As Float = 0.00 To 6.27 Step theta_spacing ' < pi * 2 6.28
    Dim costheta As Float = Cos(theta)
    Dim sintheta As Float = Sin(theta)
    Dim theta1 As Float = (sinA * sintheta) 
    Dim Theta2 As Float = (costheta * sinB)
    Dim Theta3 As Float = (cosA * costheta)
    Dim Theta4 As Float = (cosA * sintheta)
    Dim Theta5 As Float = (costheta * sinA)
    Dim circlex As Float = r2 + (r1 * costheta)
    Dim circley As Float = r1 * sintheta
    
    For phi As Float = 0.00 To 6.27 Step phi_spacing '  < pi * 2 6.28
      Inc iterations
      Dim cosphi As Float = Cos(phi)
      Dim sinphi As Float = Sin(phi)

      'calc luminance
     'Dim L As Float = (cosphi * costheta * sinB) - (cosA * costheta * sinphi) - (sinA * sintheta) + (cosB * ((cosA * sintheta) - (costheta * sinA * sinphi)))
      Dim L As Float = (cosphi * Theta2) - (Theta3 * sinphi) - Theta1 + (cosB * (Theta4 - (Theta5 * sinphi)))
      ' L ranges From -sqrt(2) To + sqrt(2).If it 's < 0, the surface
      ' Is Pointing away From us, so we won 't bother trying to plot it.
      If L > 0 Then
         
      
        Dim x As Float = circlex * (cosb * cosphi + sina * sinb * sinphi) - (circley * cosa * sinB)
        Dim y As Float = circlex * (sinb * cosphi - sina * cosb * sinphi) + (circley * cosa * cosB)
      
        Dim z As Float = k2 + cosa * circlex * sinphi + circley * sina
        Dim ooz As Float = 1.00 / z
      
        'x And y projection.note that y Is Negated here, because y
        'goes up In 3D space but down On 2D displays.
        Dim xp As Integer = CInt(screen_width / 2.00 + k1 * ooz * x)
        Dim yp As Integer = CInt(screen_height / 2.00 - k1 * ooz * y)
        
				If xp < 0 Then
					xp = 0
				Else If xp >= screen_width Then
					xp = screen_width - 1
				Endif
				
				If yp < 0 Then
					yp = 0
				Else If yp >= screen_height Then
					yp = screen_height - 1
				Endif
        
        If ooz > zbuffer[xp, yp] Then
          zbuffer[xp, yp] = ooz
          bOutput[xp, yp] = Asc(" .,-~:;=!*$#@", 1 + Abs(CInt(L * 8)))
        Endif
      Endif
      
    Next
    
  Next
  'print to the screen
  Print "\e[J\e[H";
  Flush
  sBuffer = ""
  For j As Integer = 0 To screen_height - 1
    For i As Integer = 0 To screen_width - 1
			sBuffer &= Chr(bOutput[i, j])
    Next
    sBuffer &= "\n"
  Next
  Print Left$(sBuffer, -1);
End




More information about the User mailing list