Trick - ProcedureReturn für "kleine" Strukturen
Verfasst: 07.08.2011 17:28
Es scheint ja immer wieder Leute zu geben, die Probleme damit haben, dass Prozeduren keine Strukturen zurück geben können.
Um mal eine andere Möglichkeit, außer die Benutzung von Pointer innerhalb der Parameter, zu zeigen, möchte ich hier mal folgenden "trickreichen" Code zeigen, um zB. zwei Floats (also ein 2D-Vektor) zurück zu geben:
Der Trick ist, den größtmöglichen Standard-Typ (Quad) als Speicherbuffer für zB zwei Floats zu "missbrauchen".
Außerhalb wird diese Mini-Struktur dann wie eine Quad behandelt.
Innerhalb der Prozeduren kann man sich die beiden Floats aufschlüsseln.
Mit Hilfe einiger geeigneter Prozeduren kann man sich damit schnell eine Include für 2D-Vektoren bauen, die ohne Pointer auskommt:
Um mal eine andere Möglichkeit, außer die Benutzung von Pointer innerhalb der Parameter, zu zeigen, möchte ich hier mal folgenden "trickreichen" Code zeigen, um zB. zwei Floats (also ein 2D-Vektor) zurück zu geben:
Der Trick ist, den größtmöglichen Standard-Typ (Quad) als Speicherbuffer für zB zwei Floats zu "missbrauchen".
Außerhalb wird diese Mini-Struktur dann wie eine Quad behandelt.
Innerhalb der Prozeduren kann man sich die beiden Floats aufschlüsseln.
Mit Hilfe einiger geeigneter Prozeduren kann man sich damit schnell eine Include für 2D-Vektoren bauen, die ohne Pointer auskommt:
Code: Alles auswählen
Structure Float2D
StructureUnion
Quad.q : Float.f[2]
EndStructureUnion
EndStructure
Procedure.q Float2D(X.f, Y.f)
Protected Object.Float2D
Object\Float[0] = X : Object\Float[1] = Y
ProcedureReturn Object\Quad
EndProcedure
Procedure.q Plus2D(A.q, B.q)
Protected *Object1.Float2D = @A, *Object2.Float2D = @B
ProcedureReturn Float2D(*Object1\Float[0]+*Object2\Float[0], *Object1\Float[1]+*Object2\Float[1])
EndProcedure
Procedure.q Minus2D(A.q, B.q)
Protected *Object1.Float2D = @A, *Object2.Float2D = @B
ProcedureReturn Float2D(*Object1\Float[0]-*Object2\Float[0], *Object1\Float[1]-*Object2\Float[1])
EndProcedure
Procedure.q Times2D(A.q, Factor.f)
Protected *Object.Float2D = @A
ProcedureReturn Float2D(*Object\Float[0]*Factor, *Object\Float[1]*Factor)
EndProcedure
Procedure.f Scalar2D(A.q, B.q)
Protected *Object1.Float2D = @A, *Object2.Float2D = @B
ProcedureReturn *Object1\Float[0]**Object2\Float[0] + *Object1\Float[1]**Object2\Float[1]
EndProcedure
Procedure.q Rotate2D(A.q, Angle.f)
Protected *Object.Float2D = @A
ProcedureReturn Float2D(*Object\Float[0]*Cos(Angle)-*Object\Float[1]*Sin(Angle), *Object\Float[0]*Sin(Angle)+*Object\Float[1]*Cos(Angle))
EndProcedure
Procedure.f Abs2D(A.q)
ProcedureReturn Sqr(Scalar2D(A, A))
EndProcedure
Procedure.q Normalize2D(A.q)
Protected Abs.f = Abs2D(A)
If Abs
ProcedureReturn Times2D(A, 1/Abs)
Else
ProcedureReturn A
EndIf
EndProcedure
Procedure.s Return2D(A.q)
Protected *Object.Float2D = @A
ProcedureReturn StrF(*Object\Float[0])+" , "+StrF(*Object\Float[1])
EndProcedure
Procedure.f ReturnX(A.q)
Protected *Object.Float2D = @A
ProcedureReturn *Object\Float[0]
EndProcedure
Procedure.f ReturnY(A.q)
Protected *Object.Float2D = @A
ProcedureReturn *Object\Float[1]
EndProcedure
A.q = Float2D(3, 4)
Debug Return2D(A)
Debug ReturnX(A)
Debug ReturnY(A)
Debug Abs2D(A)
Debug ""
C.q = Minus2D(A, Float2D(3.0, -0.5))
Debug Return2D(C)
Debug ""
D.q = Rotate2D(Float2D(1.0, 0.0), Radian(45))
Debug Return2D(Times2D(D,100))
Debug ""
Debug Return2D(Normalize2D(Float2D(3,4)))