[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