Zoom and Rotation Gesture for Android

Monkey Forums/Monkey Code/Zoom and Rotation Gesture for Android

Midimaster(Posted 2012) [#1]
Here is a homemade gesture detection. Nothing special..., without native Android functions..., but it works....

To use it you only need the Class Gesture, but the code is also a executable sample.

The Class can detect Zooming, Moving, Rotating and Clicking Gestures.

It could be possible, that it works also on other devices, which support multi-touch.


*** updated: V=0.81 ***

[monkeycode]Strict
Import mojo

Class GestureTest Extends App

Field MyScale#=1, MyRotation%=0, MyBoxColor%, MyX%, MyY%
Field Gestures:Gestures


Method OnCreate%()
Gestures=New Gestures
SetUpdateRate 30
Return 0
End



Method OnUpdate%()

If KeyHit(KEY_ESCAPE) Then Error ""

' check gestures:
Gestures.Update()

'set final values, if a gestures was finished:
' Zoom:
MyScale=MyScale*Gestures.LastZoom()
' rotation:
MyRotation=MyRotation + Gestures.LastAngle()
' Movement:
MyX=MyX + Gestures.LastX()
MyY=MyY + Gestures.LastY()
' TouchHit():
If Gestures.ItWasAHit()
MyBoxColor=Int(Rnd(5))
End

Return 0
End





Method OnRender%()
Cls

' change temp.values of running gesture:
'zoom:
Local ActScale#=MyScale*Gestures.TempZoom()
'rotation:
Local ActRotation%=MyRotation+Gestures.TempAngle()
Local ActTranslationX%=MyX+Gestures.TempX()
Local ActTranslationY%=MyY+Gestures.TempY()

Translate 120,160
Translate ActTranslationX,ActTranslationY
Scale ActScale,ActScale
Rotate ActRotation

DrawRect -50,-40,100,80
' Color indicates a TouchHit()
SetColorIndex MyBoxColor
DrawRect -50,-40,100,20
Return 0
End

End



Function Main%()
New GestureTest
Return 0
End



Function SetColorIndex:Void(No%)
Select No
Case 0
SetColor 255,0,0
Case 1
SetColor 255,255,0
Case 2
SetColor 0,255,0
Case 3
SetColor 255,0,255
Case 4
SetColor 0,0,255
End Select
End


Class Gestures
'
' can detect zoom and rotaion gestures on Android and can differ these from TouchHit(). During one
' gesture only 'Zoom' OR 'Rotation' OR 'Movement' OR 'TouchHit' can happen.
'
' During a gesture the current values are offered in:
' TempZoom#() TempAngle#() TempX#() TempY#()
' At the end of the gesture call:
' LastZoom#() LastAngle#() ItWasAHit%() LastX#() LastY#()
' ... to get the final values
'
' ZOOMING:
' TempZoom#() LastZoom#() return values form 0.01 to 1 and 1 to 100 as a scaling factor
' ROTATION:
' TempAngle#() LastAngle#() return values from -360° to +360° in degrees
' MOVEMENT:
' TempX#() TempY#() LastX#() LastY#() return values in from -1024 to 1024 pixels
' TOUCHHIT:
' ItWasAHit%() returns FALSE if a Zoom or Rotation was detected and TRUE if it was a simple TouchHit()
'
Field NewHit%=FALSE
Field StartZoom#, LastZoomValue#=1,TempZoomValue#=1
Field StartAngle#,LastAngleValue#=0, TempAngleValue#=0
Field StartX%, StartY%, LastXValue%, LastYValue%, TempXValue%, TempYValue%

Field GestureTyp%
Const G_ONE%=1, G_HIT%=2, G_BOTH%=4, G_MOVE%=8, G_ZOOM%=16, G_ROTATE%=32

Method Update:Void()

'check current values of zoom And rotation
Local NowZoom#= Pow(TouchX(0)-TouchX(1),2) + Pow(TouchY(0)-TouchY(1),2)
Local NowAngle% = (360+ ATan2( TouchX(0)-TouchX(1), TouchY(0)-TouchY(1) ) ) Mod 360
Local NowX%=TouchX(0)
Local NowY%=TouchY(0)
TempZoomValue=1
TempAngleValue=0
TempXValue=0
TempYValue=0

'check if both fingers are down:
If TouchDown(0) And TouchDown(1)

If GestureTyp<G_BOTH
GestureTyp=G_BOTH
' start up: store values for zoom and rotation
StartZoom=NowZoom
StartAngle = NowAngle
Endif


Local locZoom#=NowZoom/StartZoom
' store values difference since start
Select GestureTyp
Case G_ROTATE
TempAngleValue = NowAngle-StartAngle
Case G_ZOOM
TempZoomValue=locZoom
Case G_BOTH
If ((Abs(NowAngle-StartAngle)>15) )
GestureTyp=G_ROTATE
TempAngleValue = NowAngle-StartAngle
Elseif (locZoom>1.2) Or (locZoom<0.8)
TempZoomValue=locZoom
GestureTyp=G_ZOOM
Endif
End Select

' no, only one finger is down:
Elseif TouchDown(0)
' long enough?
If GestureTyp=0
' start up: store values for movement
GestureTyp=G_ONE
StartX=NowX
StartY=NowY
Endif


Select GestureTyp
' store values difference since start
Case G_MOVE
TempXValue=NowX-StartX
TempYValue=NowY -StartY
Case G_ONE
If Pow(NowX-StartX,2)+Pow(NowY-StartY,2)>20
Print "move"
GestureTyp=G_MOVE
TempXValue=NowX-StartX
TempYValue=NowY-StartY
Endif
End Select



' no, fingers released:
Else
If GestureTyp>0

' now make the new values become the final
Select GestureTyp
Case G_ROTATE
LastAngleValue= NowAngle-StartAngle
Case G_ZOOM
LastZoomValue= NowZoom/StartZoom
Case G_MOVE
Print "was move"
LastXValue=NowX-StartX
LastYValue=NowY-StartY
Default
Print "hit"
NewHit=True
End Select
GestureTyp=0
Endif
Endif
End



Method LastZoom#()
Local loc#=LastZoomValue
' is it a final value?
'no:
If loc=1 Then Return 1
'yes:
'reset last values for next gesture:
LastZoomValue=1
'TempZoomValue=1
Return loc
End Method



Method LastAngle#()
Local loc#= LastAngleValue
' is it a final value?
'no:
If loc=0 Then Return 0
'yes:
'reset last values for next gesture:
LastAngleValue=0
'TempAngleValue=0
Return loc
End Method



Method LastX#()
Local loc#=LastXValue
' is it a final value?
'no:
If loc=1 Then Return 0
'yes:
'reset last values for next gesture:
LastXValue=0
'TempZoomValue=1
Return loc
End





Method LastY#()
Local loc#=LastYValue
' is it a final value?
'no:
If loc=1 Then Return 0
'yes:
'reset last values for next gesture:
LastYValue=0
'TempZoomValue=1
Return loc
End



Method ItWasAHit%()
Local loc%= NewHit
'reset temp value for next gesture:
NewHit=FALSE
Return loc
End



Method TempZoom#()
' return value, but do not reset
Return TempZoomValue
End



Method TempAngle#()
' return value, but do not reset
Return TempAngleValue
End

Method TempX#()
' return value, but do not reset
Return TempXValue
End

Method TempY#()
' return value, but do not reset
Return TempYValue
End
End
[/monkeycode]


Why0Why(Posted 2012) [#2]
Thanks for sharing!