Amount of rotation on matrix?

Community Forums/Monkey Talk/Amount of rotation on matrix?

orgos(Posted 2011) [#1]
Hi

I'm working on some experiments for a simple Monkey framework, I have two kind of objects tScene and the other tImage

On the Draw method of each one, they make some Matrix(translate, scale and rotation) operation, so when the tScene render, it apply his matrix transformation and then call the tImage render method, and the tImage render apply his matrix transformation too.

I want to calculate the region of tImage using his size, to perform some collision. To make this I need the total amount of Matrix rotation applied until the Render call of current object.

I'm very rookie using matrix, so I need help to figure out about how to obtain the total amount of matrix rotation or something.

Thanks.


Warpy(Posted 2011) [#2]
To begin with: I've written explanations of the maths behind matrix transformations about a bajillion times, so for reference here's one of them.

The formula for a general transformation is
nx = ix*x + iy*y + tx
ny = jx*y + jy*y + ty


Now, when you use GetMatrix you get an array of the form [ix,iy,jx,jy,tx,ty].
If you've got a matrix representing a scale transformation of size U,V (so x-coordinates multiplied by U, y-coordinates multiplied by V), and rotation by R degrees, the first four parts of the transformation matrix are worked out like so:
ix = U*Cos(r)
iy = -U*Sin(r)
jx = V*Sin(r)
jy = V*Cos(r)


Making use of the fact that Cos(x)^2 + Sin(x)^2 = 1, we can get:
ix*ix + iy*iy = U^2*(Cos(R)^2 + Sin(R)^2) = U^2*1 = U^2


So we can work out R like so:
U = Sqr(ix*ix+iy*iy)
cr = ix/U
R = ACos(cr)



orgos(Posted 2011) [#3]
Hi Warpy thanks for the reply but I think this not work properly.

Look this code:


Strict

Import mojo


Function Main:Void()
	New mygame 
End


Class mygame Extends App

	Field angle1:Float = 0
	Field angle2:Float = 0

	Method OnCreate:Int()
		SetUpdateRate(60)
		Return 0
	End
	
	Method OnUpdate:Int()
		If KeyDown(KEY_Q)
			Self.angle1-=1
		End

		If KeyDown(KEY_E)
			Self.angle1+=1
		End
		
		If KeyDown(KEY_O)
			Self.angle2-=1
		End

		If KeyDown(KEY_P)
			Self.angle2+=1
		End
		
		Return 0		
	End
	
	
	Method OnRender:Int()
		Cls (100, 100, 100)
		PushMatrix()
			'Translate(10, 10)
			Rotate(angle1)
			'Print angule
			

			'0 y 3 scalas
			'4 y 5 coordenadas
			
			PushMatrix()
			Translate(50, 50)
			Rotate(angle2)
			Translate(-50, -50)
			'Scale(-1,-1)
			
			DrawRect(0, 0, 100, 100)
			DrawLine(50,-100, 50, 1000)
				Local matrix:Float[] = GetMatrix()
			PopMatrix()
			
		PopMatrix()
		
		
		DrawText "0:"+matrix[0], 300,0
		DrawText "1:"+matrix[1], 300,20
		DrawText "2:"+matrix[2], 300,40
		DrawText "3:"+matrix[3], 300,60
		DrawText "4:"+matrix[4], 300,80
		DrawText "5:"+matrix[5], 300,100

		DrawText "A:"+angle1, 300,120
		DrawText "B:"+angle2, 300,140
		
		Local U:Float = Sqrt(matrix[0]*matrix[0]+matrix[1]*matrix[1])
		Local cr:Float = matrix[0]/U
		Local R:Float = ACos(cr)
		
		DrawText "??:"+R, 0, 240
		
		Return 0
	End
End


When I apply a rotation more than 180 degrees the R value goes down.


Warpy(Posted 2011) [#4]
Right! That's because I'm stupid. In fact, you can avoid all that maths and just do:
R = ATan2(iy,ix)


Normally I make myself write some code to check what I say before I post it, but today I thought I could get away without it!