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
c50325c1
Commit
c50325c1
authored
May 08, 2012
by
Taddeus Kroes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed rotation- and pinch-detection by keeping their amounts in global variables.
parent
9eceb62b
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
87 additions
and
90 deletions
+87
-90
src/touch.py
src/touch.py
+87
-90
No files found.
src/touch.py
View file @
c50325c1
...
...
@@ -71,6 +71,12 @@ class TouchPoint(object):
def
xy
(
self
):
return
self
.
x
,
self
.
y
def
dx
(
self
):
return
self
.
x
-
self
.
px
def
dy
(
self
):
return
self
.
y
-
self
.
py
def
update
(
self
,
x
,
y
):
self
.
update_time
=
time
.
time
()
self
.
px
=
self
.
x
...
...
@@ -78,43 +84,21 @@ 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
distance_to_prev
(
self
):
return
self
.
distance_to
(
self
.
px
,
self
.
py
)
def
set_centroid
(
self
,
cx
,
cy
):
self
.
pinch
=
self
.
distance_to
(
cx
,
cy
)
self
.
angle
=
atan2
(
cy
-
self
.
y
,
self
.
x
-
cx
)
if
self
.
pinch
!=
None
:
self
.
old_pinch
=
self
.
pinch
self
.
old_angle
=
self
.
angle
self
.
pinch
=
pinch
self
.
angle
=
angle
else
:
self
.
old_pinch
=
self
.
pinch
=
pinch
self
.
old_angle
=
self
.
angle
=
angle
def
angle_diff
(
self
):
return
self
.
angle
-
self
.
old_angle
def
pinch_diff
(
self
):
return
self
.
pinch
-
self
.
old_pinch
def
dx
(
self
):
return
self
.
x
-
self
.
px
def
dy
(
self
):
return
self
.
y
-
self
.
py
def
down_time
(
self
):
return
time
.
time
()
-
self
.
start_time
def
angle
(
self
,
cx
,
cy
):
return
atan2
(
cy
-
self
.
y
,
self
.
x
-
cx
)
def
distance
(
self
,
other_x
,
other_y
):
return
distance
((
self
.
x
,
self
.
y
),
(
other_x
,
other_y
))
def
is_tap
(
self
):
return
self
.
distance_to_prev
()
<
TAP_TIME
\
and
self
.
distance_to
(
self
.
start_x
,
self
.
start_y
)
<
TAP_DISTANCE
return
time
.
time
()
-
self
.
update_time
<
TAP_TIME
\
and
self
.
distance
(
self
.
start_x
,
self
.
start_y
)
<
TAP_DISTANCE
def
distance_to_prev
(
self
):
return
self
.
distance
(
self
.
px
,
self
.
py
)
def
is_stationary
(
self
):
return
self
.
distance_to_prev
()
<
DIST_THRESHOLD
...
...
@@ -134,10 +118,12 @@ class MultiTouchListener(Logger):
self
.
points
=
[]
# Put centroid outside screen to prevent misinterpretation
self
.
centroid
=
(
-
1.
,
-
1.
)
self
.
centroid
=
-
1.
,
-
1.
self
.
server
=
TuioServer2D
(
self
,
verbose
=
tuio_verbose
)
self
.
angle
=
self
.
pinch
=
None
def
point_down
(
self
,
sid
,
x
,
y
):
"""
Called by TUIO listener when a new touch point is created, triggers a
...
...
@@ -177,7 +163,7 @@ class MultiTouchListener(Logger):
t
=
time
.
time
()
if
t
-
self
.
last_tap_time
<
TAP_TIMEOUT
\
and
p
.
distance
_to
(
*
self
.
last_tap
.
xy
)
<
DOUBLE_TAP_DISTANCE
:
and
p
.
distance
(
*
self
.
last_tap
.
xy
)
<
DOUBLE_TAP_DISTANCE
:
self
.
trigger
(
DoubleTap
(
p
.
x
,
p
.
y
))
self
.
last_tap
=
None
self
.
last_tap_time
=
0
...
...
@@ -200,7 +186,7 @@ class MultiTouchListener(Logger):
"""
p
=
self
.
find_point
(
sid
)
if
p
.
distance
_to
(
x
,
y
)
>
DIST_THRESHOLD
:
if
p
.
distance
(
x
,
y
)
>
DIST_THRESHOLD
:
p
.
update
(
x
,
y
)
self
.
trigger
(
MoveEvent
(
p
))
self
.
points_changed
=
True
...
...
@@ -215,33 +201,77 @@ class MultiTouchListener(Logger):
if
l
<
2
or
(
'pinch'
not
in
self
.
handlers
\
and
'rotate'
not
in
self
.
handlers
):
self
.
set_state
(
None
,
None
)
return
self
.
calc_state
()
rotation
,
pinch
=
self
.
state_diff
()
cx
,
cy
=
self
.
centroid
#rotation = pinch = 0
#for p in self.points
:
# da = p.angle_diff(
)
if
rotation
:
self
.
trigger
(
Rotate
(
cx
,
cy
,
rotation
,
l
)
)
# # Assert that angle is in [-pi, pi]
# if da > pi:
# da -= 2 * pi
# elif da < pi:
# da += 2 * pi
if
pinch
:
self
.
trigger
(
Pinch
(
cx
,
cy
,
pinch
,
l
))
# rotation += da
# pinch += p.pinch_diff()
def
calc_state
(
self
):
l
=
len
(
self
.
points
)
cx
,
cy
=
self
.
centroid
angle
=
reduce
(
add
,
[
p
.
angle
(
cx
,
cy
)
for
p
in
self
.
points
])
/
l
distance
=
reduce
(
add
,
[
p
.
distance
(
cx
,
cy
)
for
p
in
self
.
points
])
/
l
angles
,
pinches
=
zip
(
*
[(
p
.
angle_diff
(),
p
.
pinch_diff
())
for
p
in
self
.
points
])
rotation
=
reduce
(
add
,
angles
)
pinch
=
reduce
(
add
,
pinches
)
if
self
.
angle
==
None
:
self
.
set_state
(
angle
,
distance
)
self
.
set_prev_state
()
else
:
self
.
set_prev_state
()
self
.
set_state
(
angle
,
distance
)
if
rotation
:
self
.
trigger
(
Rotate
(
cx
,
cy
,
rotation
/
l
,
l
))
def
set_state
(
self
,
angle
,
distance
):
self
.
angle
=
angle
self
.
distance
=
distance
if
pinch
:
self
.
trigger
(
Pinch
(
cx
,
cy
,
pinch
/
l
*
2
,
l
))
def
set_prev_state
(
self
):
self
.
prev_angle
=
self
.
angle
self
.
prev_distance
=
self
.
distance
def
state_diff
(
self
):
da
=
self
.
angle
-
self
.
prev_angle
# Assert that angle is in [-pi, pi]
#if da > pi:
# da %= 2 * pi
#elif da < -pi:
# da %= -2 * pi
return
da
,
self
.
distance
/
self
.
prev_distance
def
update_centroid
(
self
):
"""
Calculate the centroid of all current touch points.
"""
self
.
old_centroid
=
self
.
centroid
l
=
len
(
self
.
points
)
# If there are no touch points, move the centroid to outside the screen
if
not
l
:
self
.
centroid
=
-
1.
,
-
1.
return
# Only use stationary points, if any
use
=
filter
(
TouchPoint
.
is_stationary
,
self
.
points
)
if
not
len
(
use
):
use
=
self
.
points
cx
,
cy
=
zip
(
*
[(
p
.
x
,
p
.
y
)
for
p
in
use
])
self
.
centroid
=
reduce
(
add
,
cx
,
0
)
/
l
,
reduce
(
add
,
cy
,
0
)
/
l
def
centroid_movement
(
self
):
cx
,
cy
=
self
.
centroid
ocx
,
ocy
=
self
.
old_centroid
return
cx
-
ocx
,
cy
-
ocy
def
detect_pan
(
self
):
"""
...
...
@@ -254,9 +284,9 @@ class MultiTouchListener(Logger):
return
False
m
=
MAX_MULTI_DRAG_DISTANCE
clustered
=
l
==
1
or
all
([
p
.
distance
_to
(
*
self
.
centroid
)
<=
m
\
clustered
=
l
==
1
or
all
([
p
.
distance
(
*
self
.
centroid
)
<=
m
\
for
p
in
self
.
points
])
directions
=
[(
cmp
(
p
.
dx
(),
0
),
cmp
(
p
.
dy
(),
0
))
\
directions
=
[(
cmp
(
p
.
dx
(),
0
),
cmp
(
p
.
dy
(),
0
))
for
p
in
self
.
points
]
if
not
clustered
or
not
any
(
map
(
all
,
zip
(
*
directions
))):
...
...
@@ -282,15 +312,6 @@ class MultiTouchListener(Logger):
if
index
:
return
-
1
,
None
def
detect_pinch
(
self
,
moved
):
cx
,
cy
=
self
.
centroid
dist
=
moved
.
distance_to
(
cx
,
cy
)
old_dist
=
distance
((
moved
.
px
,
moved
.
py
),
self
.
centroid
)
if
abs
(
dist
-
old_dist
)
>
DIST_THRESHOLD
:
self
.
trigger
(
Pinch
(
cx
,
cy
,
dist
/
old_dist
,
len
(
self
.
points
)))
def
detect_single_tap
(
self
):
"""
Check if a single tap event should be triggered by checking is the last
...
...
@@ -301,31 +322,6 @@ class MultiTouchListener(Logger):
self
.
last_tap
=
None
self
.
last_tap_time
=
0
def
update_centroid
(
self
):
"""
Calculate the centroid of all current touch points.
"""
self
.
old_centroid
=
self
.
centroid
l
=
len
(
self
.
points
)
# If there are no touch points, move the entroid to outside the screen
if
not
l
:
self
.
centroid
=
(
-
1.
,
-
1.
)
return
cx
,
cy
=
zip
(
*
[(
p
.
x
,
p
.
y
)
for
p
in
self
.
points
])
self
.
centroid
=
(
reduce
(
add
,
cx
,
0
)
/
l
,
reduce
(
add
,
cy
,
0
)
/
l
)
# Update angle and pinch of all touch points
for
p
in
self
.
points
:
p
.
set_centroid
(
*
self
.
centroid
)
def
centroid_movement
(
self
):
cx
,
cy
=
self
.
centroid
ocx
,
ocy
=
self
.
old_centroid
return
cx
-
ocx
,
cy
-
ocy
def
detect_gestures
(
self
):
"""
Detect if any gestures have occured in the past gesture frame. This
...
...
@@ -432,6 +428,7 @@ if __name__ == '__main__':
listener
.
bind
(
'single_tap'
,
tap
,
1
)
listener
.
bind
(
'double_tap'
,
tap
,
2
)
listener
.
bind
(
'rotate'
,
lambda
e
:
0
)
listener
.
bind
(
'pinch'
,
lambda
e
:
0
)
try
:
listener
.
start
()
...
...
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