RosettaCodeData/Task/Death-Star/FreeBASIC/death-star-1.basic

97 lines
2.7 KiB
Plaintext

Enum
x_
y_
z_
r_
End Enum
Function clamp(x As Double, b As Double, t As Double) As Double
If x < b Then
Return b
Elseif x > t Then
Return t
Else
Return x
End If
End Function
Function dot(v() As Double, w() As Double) As Double
Return v(x_) * w(x_) + v(y_) * w(y_) + v(z_) * w(z_)
End Function
Sub normal(v() As Double, result() As Double)
Dim As Double ilen = 1 / Sqr(dot(v(), v()))
result(x_) = v(x_) * ilen
result(y_) = v(y_) * ilen
result(z_) = v(z_) * ilen
End Sub
Function hitTest(s() As Double, x As Double, y As Double, result() As Double) As Boolean
Dim As Double z = s(r_)^2 - (x - s(x_))^2 - (y - s(y_))^2
If z >= 0 Then
z = Sqr(z)
result(0) = s(z_) - z
result(1) = s(z_) + z
Return True
Else
Return False
End If
End Function
Sub DeathStar(posic() As Double, neg() As Double, sun() As Double, k As Double, amb As Double)
Dim As Double x, y, b
Dim As String shades(10) = {" ", ".", ":", "!", "*", "o", "e", "&", "#", "%", "@"}
Dim As Integer result, shade
Dim As Double hp(1), hn(1), xx(2), temp1(2), temp2(2)
For y = posic(y_) - posic(r_) - 0.5 To posic(y_) + posic(r_) + 0.5 Step 1
For x = posic(x_) - posic(r_) - 0.5 To posic(x_) + posic(r_) + 0.5 Step 1
If hitTest(posic(), x, y, hp()) = 0 Then
result = 0
Elseif hitTest(neg(), x, y, hn()) = 0 Then
result = 1
Elseif hn(0) > hp(0) Then
result = 1
Elseif hn(1) > hp(1) Then
result = 0
Elseif hn(1) > hp(0) Then
result = 2
Else
result = 1
End If
shade = -1
Select Case result
Case 0
shade = 0
Case 1
temp1(x_) = x - posic(x_)
temp1(y_) = y - posic(y_)
temp1(z_) = hp(0) - posic(z_)
normal(temp1(), xx())
Case 2
temp2(x_) = neg(x_) - x
temp2(y_) = neg(y_) - y
temp2(z_) = neg(z_) - hn(1)
normal(temp2(), xx())
End Select
If shade <> 0 Then
b = dot(sun(), xx())^k + amb
shade = clamp((1 - b) * Ubound(shades), 1, Ubound(shades))
End If
Print String(2, shades(shade));
Next
Print
Next
End Sub
Dim As Double posic(3) = {20, 20, 0, 20}
Dim As Double neg(3) = {10, 10, -15, 10}
Dim As Double sun(2)
Dim As Double temp3(2) = {-2, 1, 3}
normal(temp3(), sun())
DeathStar(posic(), neg(), sun(), 2, 0.1)
Sleep