Innostuin tässä kehittelemään uudestaan tuota vanhaa objektijärjestelmääni, ja satuin tarvitsemaan siihen GetAngle-funktiota, joten väsäsin tälläisen:
Code: Select all
Function GetAngle(Var x1 As Float,Var y1 As Float,Var x2 As Float, Var y2 As Float) As Float
Var x As Float=x2-x1
Var y As Float=y2-y1
If x>0 Then
Return ATan(y/x)
ElseIf x<0 Then
If y<0 Then
Return 180 + ATan(y/x)
ElseIf y>0 Then
Return ATan(y/x) -180
Else
Return 180
EndIf
ElseIf x==0 Then
If y<0 Then
Return 270
Else
Return 90
EndIf
EndIf
EndFunction
Tiedän, että edellisellä sivulla oli jo yksi, mutta siinä oletetaan, että y-akseli kasvaa alaspäin, eli se on siis suunniteltu ruutukoordinaattien mukaan. Sen lisäksi, että omani olettaa että y-akseli kasvaa ylöspäin, tarjoaa se myös nopeutta lisää n.30%. Jos joku haluaa nopeustestiohjelmani, niin se on tässä (alussa on konfigurointi parametrit):
Code: Select all
Const Var KIERROKSET=5 //Montako kertaa testiä ajetaan
Const Var KUTSUJEN_MAARA=10^6 //montako kertaa funktiota kutsutaan testin aikana
Const Var TESTITAPAUSTEN_MAARA=10000 //montako erilaista tapausta arvotaan testattavaksi
Function GetAngleNew(Var x1 As Float,Var y1 As Float,Var x2 As Float, Var y2 As Float) As Float
Var x As Float=x2-x1
Var y As Float=y2-y1
If x>0 Then
Return ATan(y/x)
ElseIf x<0 Then
If y<0 Then
Return 180 + ATan(y/x)
ElseIf y>0 Then
Return ATan(y/x) -180
Else
Return 180
EndIf
ElseIf x==0 Then
If y<0 Then
Return 270
Else
Return 90
EndIf
EndIf
EndFunction
Function GetAngle(Var x1 As Float,Var y1 As Float,Var x2 As Float, Var y2 As Float) As Float
If x1 < x2 And y1 < y2 Then
Return 360 - ATan( Distance(0,y1,0,y2) / Distance(x1,0,x2,0) )
ElseIf x1 > x2 And y1 < y2 Then
Return 180 + ATan( Distance(0,y1,0,y2) / Distance(x1,0,x2,0) )
ElseIf x1 > x2 And y1 > y2 Then
Return 180 - ATan( Distance(0,y1,0,y2) / Distance(x1,0,x2,0) )
ElseIf x1 < x2 And y1 > y2 Then
Return ATan( Distance(0,y1,0,y2) / Distance(x1,0,x2,0) )
ElseIf x1 == x2 And y1 > y2 Then
Return 90
ElseIf x1 == x2 And y1 < y2 Then
Return 270
ElseIf x1 > x2 And y1 == y2 Then
Return 180
EndIf
EndFunction
Var arvot[2,TESTITAPAUSTEN_MAARA] As Float
Var ajat[2,KIERROKSET] As Float
Var j=0
For kierros=0 To KIERROKSET-1
For i=0 To TESTITAPAUSTEN_MAARA-1
arvot[0,i]=Randomf(0,1)
arvot[1,i]=Randomf(0,1)
Next
j=0
Var alku=Timer()
For i=0 To KUTSUJEN_MAARA-1
j+=1
If j>(TESTITAPAUSTEN_MAARA-1) Then
j=0
EndIf
GetAngle(0,0,arvot[0,j],arvot[1,j])
Next
ajat[0,kierros]=Timer()-alku
j=0
alku=Timer()
For i=0 To KUTSUJEN_MAARA-1
j+=1
If j>(TESTITAPAUSTEN_MAARA-1) Then
j=0
EndIf
GetAngleNew(0,0,arvot[0,j],arvot[1,j])
Next
ajat[1,kierros]=Timer()-alku
Next
Var ajat1=0
Var ajat2=0
For i=0 To KIERROKSET-1
ajat1+=ajat[0,i]
ajat2+=ajat[1,i]
Next
Var avgAika1 As Float=ajat1/KIERROKSET
Var avgAika2 As Float=ajat2/KIERROKSET
Var f As Font = New Font
f.Load "Arial", 26
Screen.Font f
Screen.Text 10,10,avgAika1
Screen.Text 10,30,avgAika2
Screen.Text 10,50,((avgAika1-avgAika2)/avgAika1*100)+"% nopeampi"
Screen.Draw
Screen.Wait 5000
Omanikin saa toki säädettyä toimimaan ruutukoordinaattien mukaan samalla tavalla kuin tuon toisenkin saa toimimaan "maailmakoordinaattien" mukaan, eli vaihtamalla y:tä koskevat ehdot päinvastaisiksi.
Aiheutti muuten päänvaivaa tuo ATan-funktio, kun se ei palauttanutkaan negatiivisia arvoja, vaan kiltisti suoraan astelukeman. Ihmettelin ensiksi, että miksi 360 + (-45) =675, mutta se johtuikin siitä että ATan palauttikin 315, eikä -45
EDIT: Ja lisätään tähän vielä hyvin alkeellinen Vector2d-luokka, joka käyttää tuota GetAnglea, jos jotakuta kiinnostaa:
Code: Select all
Class Vector2d
Private Var mPos[2] As Float
Public Function X() As Float
Return mPos[0]
EndFunction
Public Function X(Var x As Float) As Void
mPos[0]=x
EndFunction
Public Function Y() As Float
Return mPos[1]
EndFunction
Public Function Y(Var y As Float) As Void
mPos[1]=y
EndFunction
Public Function Magnitude() As Float
Return Sqrt(mPos[0]*mPos[0]+mPos[1]*mPos[1])
EndFunction
Public Function Magnitude(Var mag As Float) As Void
Var ang As Float=Angle()
mPos[0]=Cos(ang)*mag
mPos[1]=Sin(ang)*mag
EndFunction
Public Function Angle() As Float
Return GetAngle(0,0,mPos[0],mPos[1])
EndFunction
Public Function Angle(Var ang As Float) As Void
Var mag As Float=Magnitude()
mPos[0]=Cos(ang)*mag
mPos[1]=Sin(ang)*mag
EndFunction
Public Function Add(Var vec As Vector2d) As Void
mPos[0]+=vec.X()
mPos[1]+=vec.Y()
EndFunction
Public Function Subtract(Var vec As Vector2d) As Void
mPos[0]=mPos[0]-vec.X()
mPos[1]=mPos[1]-vec.Y()
EndFunction
Public Function Multiply(Var mul As Float) As Void
mPos[0]=mPos[0]*mul
mPos[1]=mPos[1]*mul
EndFunction
Public Function Copy() As Vector2d
Var tmp As Vector2d = New Vector2d
tmp.Set(X(),Y())
Return tmp
EndFunction
EndClass