Vector graphics (again)....<sigh>

Coders forum. Discuss techniques, swap code snippets, ask for help etc. relating to all forms of software development.
Post Reply
User avatar
RageMatrix
Baaaaaaa!
Baaaaaaa!
Posts: 5515
Joined: Fri May 10, 2002 12:52 pm 0
XBL Gamertag: Jon256
Location: East Sussex

Vector graphics (again)....<sigh>

Post by RageMatrix »

<sigh>....Again with the vectors. I really wish I knew a little more about how this was working. I think my main problem was getting a rotation algo from a book that I really didn't understand all that well.
My problem is this. I create a grid of nine points, 3 by 3. Point 5 is the middle point and is also the origin of the grid.
I have a translate function which updates the origin of the grid and updates all the points relative to that origin.

So, the steps being: -

1. Create the grid at the orign (0,0) Create all points in this grid relative to this "world" origin.
2. Translate the grid to the middle of the screen, updating all points relative to the new origin.
3. Draw to the screen.

Funky. All works a treat. My major headache is the rotation code I'm using. You can see this by using the left and right arrow keys to rotate the grid. Duh? This seems to be a well-documented problem when rotating, the solution being to translate the shape back to the world origin (in this case being (0,0) at the top left of the screen, and then rotating while finally translating it back to the original position.

Could someone more mathematically inclined than me check out my code and tell me if I'm on the right track?

Basically, all I'm trying to do is create rotation, scaling and translation functions for a set of points round an origin which can be anywhere on screen. I guess I really just need to know if you need to translate to the world origin, rotate, and then translate back.

As I said, probably a mistake to use a rotation function that I didn't really understand in the first place. :)

Thanks,

Blitz Plus Code follows...

Rage_Matrix

Code: Select all

Const KEY_LEFT = 203
Const KEY_RIGHT = 205
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 CharVectorFrame
	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 tCharFrame.CharVectorFrame


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

Gosub PrecalculateSine
Gosub PrecalculateCos

tCharFrame = CreateCharFrame(300, 300)
TranslateCharFrame(tCharFrame, GFX_X / 2, GFX_Y / 2)
While Not KeyDown(1)
	Cls
	If KeyHit(KEY_F) Then
		bToggle% = Not bToggle%
	End If
	If KeyDown(KEY_LEFT) Then
		RotateCharFrame(tCharFrame, 1)
	End If
	If KeyDown(KEY_RIGHT) Then
		RotateCharFrame(tCharFrame, -1)
	End If
	DrawCharFrame(tCharFrame)
	Gosub CalculateFPS
	Gosub PrintDetails
	Flip bToggle%
Wend
End

Function CreateCharFrame.CharVectorFrame(Width#, Height#)
	Local tFrame.CharVectorFrame = New CharVectorFrame
	tFrame\X# = 0
	tFrame\Y# = 0
	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\VectorList[0]\Y# = (tFrame\Y# - tFrame\Height# / 2)
	
	tFrame\VectorList[1] = New Vector2D
	tFrame\VectorList[1]\X# = (tFrame\X#)
	tFrame\VectorList[1]\Y# = (tFrame\Y# - tFrame\Height# / 2)
	
	tFrame\VectorList[2] = New Vector2D
	tFrame\VectorList[2]\X# = (tFrame\X# + tFrame\Width# / 2)
	tFrame\VectorList[2]\Y# = (tFrame\Y# - tFrame\Height# / 2)
	
	tFrame\VectorList[3] = New Vector2D
	tFrame\VectorList[3]\X# = (tFrame\X# - tFrame\Width# / 2)
	tFrame\VectorList[3]\Y# = (tFrame\Y#)
	
	tFrame\VectorList[4] = New Vector2D
	tFrame\VectorList[4]\X# = (tFrame\X#)
	tFrame\VectorList[4]\Y# = (tFrame\Y#)
	
	tFrame\VectorList[5] = New Vector2D
	tFrame\VectorList[5]\X# = (tFrame\X# + tFrame\Width# / 2)
	tFrame\VectorList[5]\Y# = (tFrame\Y#)
	
	tFrame\VectorList[6] = New Vector2D
	tFrame\VectorList[6]\X# = (tFrame\X# - tFrame\Width# / 2)
	tFrame\VectorList[6]\Y# = (tFrame\Y# + tFrame\Height# / 2)
	
	tFrame\VectorList[7] = New Vector2D
	tFrame\VectorList[7]\X# = (tFrame\X#)
	tFrame\VectorList[7]\Y# = (tFrame\Y# + tFrame\Height# / 2)
	
	tFrame\VectorList[8] = New Vector2D
	tFrame\VectorList[8]\X# = (tFrame\X# + tFrame\Width# / 2)
	tFrame\VectorList[8]\Y# = (tFrame\Y# + tFrame\Height# / 2)
	Return tFrame
End Function

Function TranslateCharFrame(tFrame.CharVectorFrame, X#, Y#)
	tFrame\X# = tFrame\X# + X#
	tFrame\Y# = tFrame\Y# + Y#
	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 RotateCharFrame(tFrame.CharVectorFrame, 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 DrawCharFrame(tCharFrame.CharVectorFrame)
	Color 255, 255, 255
	For i = 0 To 8
		Text tCharFrame\VectorList[i]\PosX#, tCharFrame\VectorList[i]\PosY#, i 
		Rect tCharFrame\VectorList[i]\PosX# - 6, tCharFrame\VectorList[i]\PosY# - 6, 6, 6
	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              : " + tCharFrame\Angle#
	Text 10, 33, "Frame X                  : " + tCharFrame\X#
	Text 10, 44, "Frame Y                  : " + tCharFrame\Y#
	Text 10, 66, "Point 1 Orig.        X: " + tCharFrame\VectorList[0]\X# + " Y: " + tCharFrame\VectorList[0]\Y#
	Text 10, 77, "Point 2 Orig.        X: " + tCharFrame\VectorList[1]\X# + " Y: " + tCharFrame\VectorList[1]\Y#
	Text 10, 88, "Point 3 Orig.        X: " + tCharFrame\VectorList[2]\X# + " Y: " + tCharFrame\VectorList[2]\Y#
	Text 10, 99, "Point 4 Orig.        X: " + tCharFrame\VectorList[3]\X# + " Y: " + tCharFrame\VectorList[3]\Y#
	Text 10, 111, "Point 5 Orig.        X: " + tCharFrame\VectorList[4]\X# + " Y: " + tCharFrame\VectorList[4]\Y#
	Text 10, 122, "Point 6 Orig.        X: " + tCharFrame\VectorList[5]\X# + " Y: " + tCharFrame\VectorList[5]\Y#
	Text 10, 133, "Point 7 Orig.        X: " + tCharFrame\VectorList[6]\X# + " Y: " + tCharFrame\VectorList[6]\Y#
	Text 10, 144, "Point 8 Orig.        X: " + tCharFrame\VectorList[7]\X# + " Y: " + tCharFrame\VectorList[7]\Y#
	Text 10, 155, "Point 9 Orig.        X: " + tCharFrame\VectorList[8]\X# + " Y: " + tCharFrame\VectorList[8]\Y#
	
	Text 10, 177, "Point 1 Trans.        X: " + tCharFrame\VectorList[0]\PosX# + " Y: " + tCharFrame\VectorList[0]\PosY#
	Text 10, 188, "Point 2 Trans.        X: " + tCharFrame\VectorList[1]\PosX# + " Y: " + tCharFrame\VectorList[1]\PosY#
	Text 10, 199, "Point 3 Trans.        X: " + tCharFrame\VectorList[2]\PosX# + " Y: " + tCharFrame\VectorList[2]\PosY#
	Text 10, 211, "Point 4 Trans.        X: " + tCharFrame\VectorList[3]\PosX# + " Y: " + tCharFrame\VectorList[3]\PosY#
	Text 10, 222, "Point 5 Trans.        X: " + tCharFrame\VectorList[4]\PosX# + " Y: " + tCharFrame\VectorList[4]\PosY#
	Text 10, 233, "Point 6 Trans.        X: " + tCharFrame\VectorList[5]\PosX# + " Y: " + tCharFrame\VectorList[5]\PosY#
	Text 10, 244, "Point 7 Trans.        X: " + tCharFrame\VectorList[6]\PosX# + " Y: " + tCharFrame\VectorList[6]\PosY#
	Text 10, 255, "Point 8 Trans.        X: " + tCharFrame\VectorList[7]\PosX# + " Y: " + tCharFrame\VectorList[7]\PosY#
	Text 10, 266, "Point 9 Trans.        X: " + tCharFrame\VectorList[8]\PosX# + " Y: " + tCharFrame\VectorList[8]\PosY#
	
	Text 10, GFX_Y - 20, "Press F to toggle monitor vertical sync framerate clamp. It is now: " + ReturnSwitch$(bToggle%)
Return
XBox Gamertag: Jon256
Wii Code: 4849 1090 9042 6725
"Wrapped in metal, wrapped in ivy"
The Official UNIX/Linux Thread
Riff
Posts: 22
Joined: Thu Sep 05, 2002 9:34 pm 0
Location: New Hope, MN

Post by Riff »

Yes, you have to translate back. The rotation matrices or rotation components of a matrix are always for rotation about the origin of the coordinate axes. To rotate an object around a point in object space, you must first translate to the origin in screen space, perform the rotation, and then translate back to the object coordinate space. You can use a 4x4 matrix to allow rotation, scaling and translation to be represented in a single matrix. The operations will always be of the form T*M*T', where T is a transformation matrix. You can algebraically perform the matrix multiplies to obtain a set of composite formulas that will yield transformed points in one fell swoop. This can be beneficial if you need to do a large number of transformations (A*B*C*M*C'*B'*A').
Post Reply