Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
multitouch
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Taddeüs Kroes
multitouch
Commits
ea38f361
Commit
ea38f361
authored
Apr 24, 2012
by
Taddeus Kroes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Finished rewriting TouchProcessor.pde.
parent
5132ece7
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
114 additions
and
14 deletions
+114
-14
src/multitouch/events.py
src/multitouch/events.py
+41
-1
src/multitouch/touch.py
src/multitouch/touch.py
+73
-13
No files found.
src/multitouch/events.py
View file @
ea38f361
...
...
@@ -15,7 +15,7 @@ def TapEvent(GestureEvent):
def
FlickEvent
(
GestureEvent
):
def
__init__
(
self
,
x
,
y
,
velocity
):
super
(
Tap
Event
,
self
).
__init__
(
'flick'
)
super
(
Flick
Event
,
self
).
__init__
(
'flick'
)
self
.
x
=
x
self
.
y
=
y
self
.
velocity
=
velocity
...
...
@@ -23,3 +23,43 @@ def FlickEvent(GestureEvent):
def
__str__
(
self
):
return
'<%s (%s, %s) velocity=%s>'
%
\
(
self
.
__class__
.
__name__
,
self
.
x
,
self
.
y
,
self
.
velocity
)
def
RotateEvent
(
GestureEvent
):
def
__init__
(
self
,
cx
,
cy
,
angle
,
n
):
super
(
RotateEvent
,
self
).
__init__
(
'rotate'
)
self
.
cx
=
cx
self
.
cy
=
cy
self
.
angle
=
angle
self
.
n
=
n
def
__str__
(
self
):
return
'<%s (%s, %s) angle=%s n=%d>'
%
\
(
self
.
__class__
.
__name__
,
self
.
x
,
self
.
y
,
self
.
angle
,
self
.
n
)
def
PinchEvent
(
GestureEvent
):
def
__init__
(
self
,
cx
,
cy
,
amount
,
n
):
super
(
RotateEvent
,
self
).
__init__
(
'pinch'
)
self
.
cx
=
cx
self
.
cy
=
cy
self
.
amount
=
amount
self
.
n
=
n
def
__str__
(
self
):
return
'<%s (%s, %s) amount=%s n=%d>'
%
\
(
self
.
__class__
.
__name__
,
self
.
x
,
self
.
y
,
self
.
amount
,
self
.
n
)
def
PanEvent
(
GestureEvent
):
def
__init__
(
self
,
x
,
y
,
dx
,
dy
,
n
):
super
(
RotateEvent
,
self
).
__init__
(
'pan'
)
self
.
x
=
x
self
.
y
=
y
self
.
dx
=
dx
self
.
dy
=
dy
self
.
n
=
n
def
__str__
(
self
):
return
'<%s (%s, %s) amount=%s n=%d>'
%
\
(
self
.
__class__
.
__name__
,
self
.
x
,
self
.
y
,
self
.
amount
,
self
.
n
)
src/multitouch/touch.py
View file @
ea38f361
#!/usr/bin/env python
from
events
import
TapEvent
,
FlickEvent
from
events
import
TapEvent
,
FlickEvent
,
RotateEvent
,
PinchEvent
,
PanEvent
import
time
from
math
import
atan2
from
threading
import
Thread
...
...
@@ -32,8 +32,11 @@ class TouchPoint(object):
self
.
x
=
x
self
.
y
=
y
def
distance_to
(
self
,
other_x
,
other_y
):
return
distance
(
self
.
x
,
self
.
y
,
other_x
,
other_y
)
def
init_gesture_data
(
self
,
cx
,
cy
):
self
.
pinch
=
self
.
old_pinch
=
distance
(
self
.
x
,
self
.
y
,
cx
,
cy
)
self
.
pinch
=
self
.
old_pinch
=
self
.
distance_to
(
cx
,
cy
)
self
.
angle
=
self
.
old_angle
=
atan2
(
self
.
y
-
cy
,
self
.
x
-
cx
)
def
set_angle
(
self
,
angle
):
...
...
@@ -44,6 +47,9 @@ class TouchPoint(object):
self
.
old_pinch
=
self
.
pinch
self
.
pinch
=
pinch
def
angle_diff
(
self
):
return
self
.
angle
-
self
.
old_angle
def
dx
(
self
):
return
int
(
self
.
x
-
self
.
px
)
...
...
@@ -51,11 +57,14 @@ class TouchPoint(object):
return
int
(
self
.
y
-
self
.
py
)
# Heuristic constants
# TODO: Encapsulate DPI resolution in distance heuristics
SUPPORTED_GESTURES
=
(
'tap'
,
'pan'
,
'flick'
,
'rotate'
,
'pinch'
)
TUIO_ADDRESS
=
(
'localhost'
,
3333
)
DOUBLE_TAP_DISTANCE
=
30
TAP_INTERVAL
=
.
200
TAP_TIMEOUT
=
.
200
MAX_MULTI_DRAG_DISTANCE
=
100
class
MultiTouchListener
(
object
):
...
...
@@ -84,11 +93,10 @@ class MultiTouchListener(object):
if
self
.
points_changed
:
self
.
update_centroid
()
# Do not try to rotate or pinch while
dragg
ing
# Do not try to rotate or pinch while
pann
ing
# This gets rid of a lot of jittery events
if
not
self
.
detect_drag
():
self
.
detect_rotation
()
self
.
detect_pinch
()
if
not
self
.
detect_pan
():
self
.
detect_rotation_and_pinch
()
self
.
points_changed
=
False
...
...
@@ -110,14 +118,63 @@ class MultiTouchListener(object):
self
.
trigger
(
TapEvent
(
*
self
.
taps
[
0
]))
self
.
taps
=
[]
def
detect_rotation
(
self
):
if
'rotate'
not
in
self
.
handlers
:
return
def
detect_rotation_and_pinch
(
self
):
"""
Rotation is the average angle change between each point and the
centroid. Pinch is the average distance change from the points to the
centroid.
"""
l
=
len
(
self
.
points
)
def
detect_pinch
(
self
):
if
'pinch'
not
in
self
.
handlers
:
if
'pinch'
not
in
self
.
handlers
or
l
<
2
:
return
rotation
=
pinch
=
0
for
p
in
self
.
points
:
p
.
set_angle
(
atan2
(
p
.
y
-
cy
,
p
.
x
-
cx
))
da
=
p
.
angle_diff
()
# Assert that angle is in [-PI, PI]
if
da
>
PI
:
da
-=
2
*
PI
elif
da
<
PI
:
da
+=
2
*
PI
rotation
+=
da
p
.
set_pinch
(
distance
(
p
.
x
,
p
.
y
,
cx
,
cy
))
pinch
+=
p
.
pinch_diff
()
if
rotation
:
self
.
trigger
(
RotateEvent
(
cx
,
cy
,
rotation
/
l
,
l
))
if
pinch
:
self
.
trigger
(
PinchEvent
(
cx
,
cy
,
pinch
/
l
,
l
))
def
detect_pan
(
self
):
"""
Look for multi-finger drag events. Multi-drag is defined as all the
fingers moving close-ish together in the same direction.
"""
l
=
len
(
self
.
points
)
m
=
MAX_MULTI_DRAG_DISTANCE
clustered
=
l
==
1
or
all
([
p
.
distance_to
(
*
self
.
centroid
)
<=
m
\
for
p
in
self
.
points
])
directions
=
[(
cmp
(
p
.
dx
(),
0
),
cmp
(
p
.
dy
(),
0
))
for
p
in
self
.
points
]
if
any
(
map
(
all
,
zip
(
*
directions
)))
and
clustered
:
if
l
==
1
:
p
=
self
.
points
[
0
]
cx
,
cy
,
dx
,
dy
=
p
.
x
,
p
.
y
,
p
.
dx
(),
p
.
dy
()
else
:
cx
,
cy
=
self
.
centroid
old_cx
,
old_cy
=
self
.
old_centroid
dx
,
dy
=
cx
-
old_cx
,
cy
-
old_cy
self
.
trigger
(
PanEvent
(
cx
,
cy
,
dx
,
dy
,
l
))
def
point_down
(
self
,
sid
,
x
,
y
):
if
sid
in
self
.
points
:
raise
KeyError
(
'Point with session id "%s" already exists.'
%
sid
)
...
...
@@ -198,7 +255,7 @@ class MultiTouchListener(object):
def
bind
(
self
,
gesture
,
handler
):
if
gesture
not
in
SUPPORTED_GESTURES
:
raise
ValueError
(
'Uns
o
pported gesture "%s".'
%
gesture
)
raise
ValueError
(
'Uns
u
pported gesture "%s".'
%
gesture
)
if
gesture
not
in
self
.
handlers
:
self
.
handlers
[
gesture
]
=
[]
...
...
@@ -207,7 +264,10 @@ class MultiTouchListener(object):
def
trigger
(
self
,
event
):
if
event
.
gesture
in
self
.
handlers
:
for
handler
in
self
.
handlers
[
event
.
gesture
]:
h
=
self
.
handlers
[
event
.
gesture
]
self
.
log
(
'Event triggered: "%s" (%d handlers)'
%
(
event
,
len
(
h
)))
for
handler
in
h
:
handler
(
event
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment