2D Vector Rotations

BlitzPlus Forums/BlitzPlus Programming/2D Vector Rotations

Rage_Matrix(Posted 2003) [#1]
Can someone tell me why, when you uncomment the Rotation function, my collection of points does not rotate around the objects origin (point 4) as it moves left and right across the screen? It looks as though its offset from itself somehow. I don't fully understand the rotation function I'm using, which doesn't help, I guess.

Been trying for ages to get this to work properly. Any help?

Code follows...

Const KEY_F = 33

Global GFX_X = 1024
Global GFX_Y = 768

Type Vector2D
	Field X#
	Field Y#
	Field PosX#
	Field PosY#
End Type

Type VectorFrame
	Field X#
	Field Y#
	Field Angle#
	Field Width#
	Field Height#
	Field VectorList.Vector2D[9]
End Type

Global FPS#
Global FFPS# = MilliSecs()
Global Counter% = 0
Global bToggle% = True

Dim SinTable#(359)
Dim CosTable#(359)

Global tMyFrame.VectorFrame

Global Offset# = -2

Graphics GFX_X, GFX_Y, 16, 0
SetBuffer BackBuffer()
SeedRnd MilliSecs()

Gosub PrecalculateSine
Gosub PrecalculateCos

tMyFrame = CreateFrame(GFX_X / 2, GFX_Y / 2, 200, 200)
TranslateFrame(tMyFrame, GFX_X / 2, GFX_Y / 2, True)
While Not KeyDown(1)
	Cls
	If KeyHit(KEY_F) Then
		bToggle% = Not bToggle%
	End If
	If ((tMyFrame\X# + tMyFrame\Width# / 2) >= GFX_X Or (tMyFrame\X# - tMyFrame\Width# / 2) <= 0) Then
		Offset# = -Offset#
	End If
	TranslateFrame(tMyFrame, Offset#, 0, False)
	;RotateFrame(tCharFrame, -1)
	DrawFrame(tMyFrame)
	Gosub CalculateFPS
	Gosub PrintDetails
	Flip bToggle%
Wend
End

Function CreateFrame.VectorFrame(X#, Y#, Width#, Height#)
	Local tFrame.VectorFrame = New VectorFrame
	tFrame\X# = X#
	tFrame\Y# = Y#
	tFrame\Width# = Width#
	tFrame\Height# = Height#
	tFrame\Angle# = 0.0
	tFrame\VectorList[0] = New Vector2D
	tFrame\VectorList[0]\X# = (tFrame\X# - (tFrame\Width# / 2)) - tFrame\X#
	tFrame\VectorList[0]\Y# = (tFrame\Y# - (tFrame\Height# / 2)) - tFrame\Y#
	
	tFrame\VectorList[1] = New Vector2D
	tFrame\VectorList[1]\X# = (tFrame\X#) - tFrame\X#
	tFrame\VectorList[1]\Y# = (tFrame\Y# - (tFrame\Height# / 2)) - tFrame\Y#
	
	tFrame\VectorList[2] = New Vector2D
	tFrame\VectorList[2]\X# = (tFrame\X# + (tFrame\Width# / 2)) - tFrame\X#
	tFrame\VectorList[2]\Y# = (tFrame\Y# - (tFrame\Height# / 2)) - tFrame\Y#
	
	tFrame\VectorList[3] = New Vector2D
	tFrame\VectorList[3]\X# = (tFrame\X# - (tFrame\Width# / 2)) - tFrame\X#
	tFrame\VectorList[3]\Y# = (tFrame\Y#) - tFrame\Y#
	
	tFrame\VectorList[4] = New Vector2D
	tFrame\VectorList[4]\X# = (tFrame\X#) - tFrame\X#
	tFrame\VectorList[4]\Y# = (tFrame\Y#) - tFrame\Y#
	
	tFrame\VectorList[5] = New Vector2D
	tFrame\VectorList[5]\X# = (tFrame\X# + (tFrame\Width# / 2)) - tFrame\X#
	tFrame\VectorList[5]\Y# = (tFrame\Y#) - tFrame\Y#
	
	tFrame\VectorList[6] = New Vector2D
	tFrame\VectorList[6]\X# = (tFrame\X# - (tFrame\Width# / 2)) - tFrame\X#
	tFrame\VectorList[6]\Y# = (tFrame\Y# + (tFrame\Height# / 2)) - tFrame\Y#
	
	tFrame\VectorList[7] = New Vector2D
	tFrame\VectorList[7]\X# = (tFrame\X#) - tFrame\X#
	tFrame\VectorList[7]\Y# = (tFrame\Y# + (tFrame\Height# / 2)) - tFrame\Y#
	
	tFrame\VectorList[8] = New Vector2D
	tFrame\VectorList[8]\X# = (tFrame\X# + (tFrame\Width# / 2)) - tFrame\X#
	tFrame\VectorList[8]\Y# = (tFrame\Y# + (tFrame\Height# / 2)) - tFrame\Y#
	Return tFrame
End Function

Function TranslateFrame(tFrame.VectorFrame, X#, Y#, bAbsolute%)
	If (bAbsolute%) Then
		tFrame\X# = X#
		tFrame\Y# = Y#
	Else
		tFrame\X# = tFrame\X# + X#
		tFrame\Y# = tFrame\Y# + Y#
	End If
	tFrame\VectorList[0]\X# = (tFrame\X# - (tFrame\Width# / 2))
	tFrame\VectorList[0]\Y# = (tFrame\Y# - (tFrame\Height# / 2))
	tFrame\VectorList[0]\PosX# = tFrame\VectorList[0]\X#
	tFrame\VectorList[0]\PosY# = tFrame\VectorList[0]\Y#
	
	tFrame\VectorList[1]\X# = (tFrame\X#)
	tFrame\VectorList[1]\Y# = (tFrame\Y# - (tFrame\Height# / 2))
	tFrame\VectorList[1]\PosX# = tFrame\VectorList[1]\X#
	tFrame\VectorList[1]\PosY# = tFrame\VectorList[1]\Y#
	
	tFrame\VectorList[2]\X# = (tFrame\X# + (tFrame\Width# / 2))
	tFrame\VectorList[2]\Y# = (tFrame\Y# - (tFrame\Height# / 2))
	tFrame\VectorList[2]\PosX# = tFrame\VectorList[2]\X#
	tFrame\VectorList[2]\PosY# = tFrame\VectorList[2]\Y#
	
	tFrame\VectorList[3]\X# = (tFrame\X# - (tFrame\Width# / 2))
	tFrame\VectorList[3]\Y# = (tFrame\Y#)
	tFrame\VectorList[3]\PosX# = tFrame\VectorList[3]\X#
	tFrame\VectorList[3]\PosY# = tFrame\VectorList[3]\Y#
	
	tFrame\VectorList[4]\X# = (tFrame\X#)
	tFrame\VectorList[4]\Y# = (tFrame\Y#)
	tFrame\VectorList[4]\PosX# = tFrame\VectorList[4]\X#
	tFrame\VectorList[4]\PosY# = tFrame\VectorList[4]\Y#
	
	tFrame\VectorList[5]\X# = (tFrame\X# + (tFrame\Width# / 2))
	tFrame\VectorList[5]\Y# = (tFrame\Y#)
	tFrame\VectorList[5]\PosX# = tFrame\VectorList[5]\X#
	tFrame\VectorList[5]\PosY# = tFrame\VectorList[5]\Y#
	
	tFrame\VectorList[6]\X# = (tFrame\X# - (tFrame\Width# / 2))
	tFrame\VectorList[6]\Y# = (tFrame\Y# + (tFrame\Height# / 2))
	tFrame\VectorList[6]\PosX# = tFrame\VectorList[6]\X#
	tFrame\VectorList[6]\PosY# = tFrame\VectorList[6]\Y#
	
	tFrame\VectorList[7]\X# = (tFrame\X#)
	tFrame\VectorList[7]\Y# = (tFrame\Y# + (tFrame\Height# / 2))
	tFrame\VectorList[7]\PosX# = tFrame\VectorList[7]\X#
	tFrame\VectorList[7]\PosY# = tFrame\VectorList[7]\Y#
	
	tFrame\VectorList[8]\X# = (tFrame\X# + (tFrame\Width# / 2))
	tFrame\VectorList[8]\Y# = (tFrame\Y# + (tFrame\Height# / 2))
	tFrame\VectorList[8]\PosX# = tFrame\VectorList[8]\X#
	tFrame\VectorList[8]\PosY# = tFrame\VectorList[8]\Y#

End Function

Function RotateFrame(tFrame.VectorFrame, AngInc#)
	tFrame\Angle# = (tFrame\Angle# + AngInc#) Mod 360
	If (tFrame\Angle# < 0) Then tFrame\Angle# = tFrame\Angle# + 360
	For i = 0 To 8
		tFrame\VectorList[i]\PosX# = (tFrame\VectorList[i]\X# * SinTable#(Int(tFrame\Angle#)) - tFrame\VectorList[i]\Y# * CosTable#(Int(tFrame\Angle#))) + tFrame\X#
		tFrame\VectorList[i]\PosY# = (tFrame\VectorList[i]\X# * CosTable#(Int(tFrame\Angle#)) + tFrame\VectorList[i]\Y# * SinTable#(Int(tFrame\Angle#))) + tFrame\Y# 
	Next
End Function

Function DrawFrame(tFrame.VectorFrame)
	Color 255, 255, 255
	For i = 0 To 8
		Text tFrame\VectorList[i]\PosX#, tFrame\VectorList[i]\PosY#, i 
		Rect tFrame\VectorList[i]\PosX# - 10, tFrame\VectorList[i]\PosY# - 10, 10, 10
	Next
End Function

.CalculateFPS
	Counter% = Counter% + 1
	If MilliSecs() >= (FFPS# + 1000) Then
		FFPS# = MilliSecs()
		FPS# = Counter%
		Counter% = 0
	End If
Return

.PrecalculateSine
	For i = 0 To 359
		SinTable#(i) = Sin(i)
	Next
Return

.PrecalculateCos
	For i = 0 To 359
		CosTable#(i) = Cos(i)
	Next
Return

Function ReturnSwitch$(bVal%)
	If (bVal%) Then
		Return "ON"
	Else
		Return "OFF"
	End If
End Function

.PrintDetails
	Color 100,100,100
	Text 10, 10, "Program Performance (fps): " + FPS#
	Text 10, 22, "Frame Angle              : " + tMyFrame\Angle#
	Text 10, 33, "Frame X                  : " + tMyFrame\X#
	Text 10, 44, "Frame Y                  : " + tMyFrame\Y#
	
	Text 10, GFX_Y - 20, "Press F to toggle monitor vertical sync framerate clamp. It is now: " + ReturnSwitch$(bToggle%)
Return


Rage_Matrix


Bremer(Posted 2003) [#2]
I haven't figured out you code 100%, but are you rotating your original points, because if so you shouldn't because that is going to screw it up. You should make copies of the points and rotate those and use the rotated values for drawing you vectors. This way the original relationship between the coordinates of the objects stays intact. At least that could be your problem. If not I'm sure someone else has an idea.


Rage_Matrix(Posted 2003) [#3]
No, I'm using copies of the original points.


Bremer(Posted 2003) [#4]
I tried to run your code, but I get an Illegal Type Conversion in this line:

RotateFrame(tCharFrame, -1)


Rage_Matrix(Posted 2003) [#5]
Erm....don't know why you get that. :) I can send you the new code if you wish or an executable. BTW, I've seen a lot of your demos. I've just registered at Dark Bit Factory and will be doing some demo coding soon for the above vector stuff. Hopefully see you on there :)


Bremer(Posted 2003) [#6]
Yeah, I'll catch you there every now and then. You should post this problem there, because some of the guys there don't come here often I think and they might be able to find the problem. I'm thinking that the problem you are having has to do with the way that you are passing types to the functions. I'm not sure that works 100% and I think I saw a post under the bugs section about that a few days ago.

I'm sure that by frequenting the DBF messageboard we'll have you coding 3D stuff in no time :)

Please do send me the code to info @ zac-interactive.com and I'll look into it as soon as I can, ok.


Who was John Galt?(Posted 2003) [#7]
I haven't tried it, but try something like

tFrame\VectorList[i]\PosX# = ((tFrame\VectorList[i]\X#-tFrame\X) * SinTable#(Int(tFrame\Angle#)) - (tFrame\VectorList[i]\Y#-tFrame\X) * CosTable#(Int(tFrame\Angle#))) + tFrame\X#


etc, and similar mod for y. This should? make the rotations be about the centre of the frame.