Hello to everyone,
I found a code from an asset which it is capable of detecting a circle gesture on a mobile screen.
I would like someone who knows how it works mathematically to explain it also to me. More specific I don’t really understand what I get from the calculation : (screen.width + screen.height) / 4. By the way the code is working correct. Thank you very much.
List<Vector2> gestureDetector = new List<Vector2>();
Vector2 gestureSum = Vector2.zero;
float gestureLength = 0;
int gestureCount = 0;
bool isGestureDone()
{
if (Input.touches.Length > 2)
{
gestureDetector.Clear();
gestureCount = 0;
}
else
{
if (Input.touches[touches - 1].phase == TouchPhase.Canceled || Input.touches[touches - 1].phase == TouchPhase.Ended)
gestureDetector.Clear();
else if (Input.touches[touches - 1].phase == TouchPhase.Moved)
{
Vector2 p = Input.touches[touches - 1].position;
if (gestureDetector.Count == 0 || (p - gestureDetector[gestureDetector.Count - 1]).magnitude > 10)
gestureDetector.Add(p);
}
}
if (gestureDetector.Count < 10)
return false;
gestureSum = Vector2.zero;
gestureLength = 0;
Vector2 prevDelta = Vector2.zero;
for (int i = 0; i < gestureDetector.Count - 2; i++)
{
Vector2 delta = gestureDetector[i + 1] - gestureDetector[i];
float deltaLength = delta.magnitude;
gestureSum += delta;
gestureLength += deltaLength;
float dot = Vector2.Dot(delta, prevDelta);
if (dot < 0f)
{
gestureDetector.Clear();
gestureCount = 0;
return false;
}
prevDelta = delta;
}
int gestureBase = (Screen.width + Screen.height) / 4;
if (gestureLength > gestureBase && gestureSum.magnitude < gestureBase / 2)
{
gestureDetector.Clear();
gestureCount++;
if (gestureCount >= numOfCircleToShow)
return true;
}
return false;
}
Let’s break down the maths aspects of your gesture detection code.
-
Initialization:
-
You start by initializing some variables:
-
gestureDetector: A list of Vector2 points that records the touch positions.
-
gestureSum: A Vector2 that accumulates the total movement.
-
gestureLength: A float that accumulates the total length of the gesture.
-
gestureCount: An integer to keep track of the number of touch points.
-
Touch Input Handling:
-
The code checks the number of active touches (Input.touches.Length). If there are more than two touches, it clears the gesture data and resets the count.
-
Otherwise, it processes the touch input:
-
If the touch phase is canceled or ended, it clears the gesture data.
-
If the touch phase is moved, it adds the current touch position to the gestureDetector list if the movement exceeds a threshold (10 units).
-
Gesture Length and Direction:
-
Once enough touch points are recorded (at least 10), the code calculates the gesture length and direction:
-
delta represents the difference between consecutive touch positions.
-
deltaLength is the magnitude (length) of the delta.
-
gestureSum accumulates the total movement by adding up the delta vectors.
-
gestureLength accumulates the total length of the gesture.
-
dot computes the dot product between the current delta and the previous delta. If the dot product is negative, it indicates a change in direction (e.g., from clockwise to counterclockwise).
-
If the direction changes, the gesture data is cleared.
-
What About (screen.width + screen.height) / 4?:
-
The expression gestureBase = (Screen.width + Screen.height) / 4 calculates a reference value for the gesture length.
-
It takes the sum of the screen width and height and divides it by 4.
-
This value serves as a baseline for determining whether the detected gesture is significant.
-
Gesture Recognition*:
-
The code checks if the gesture length exceeds the gestureBase and if the magnitude of gestureSum is less than half of gestureBase.
-
If both conditions are met, it clears the gesture data, increments the gestureCount, and checks if the required number of circles (numOfCircleToShow) has been detected.
-
If so, it returns true, indicating that a circular gesture has been recognized.
the code accumulates touch positions, calculates gesture length, and detects changes in direction. It’s a basic approach to identifying circular gestures. This simple method can work well for certain scenarios. More advanced algorithms may involve curve fitting or pattern recognition
1 Like
Here’s am implementation of curve fitting. Using the least squares regression method to fit a circle to a set of touch points. Here’s a simplified example
using System.Collections.Generic;
using UnityEngine;
public class CircularGestureDetector : MonoBehaviour
{
public int minPointsForGesture = 10; // Minimum number of touch points for a gesture
public float minRadius = 50f; // Minimum radius for a circular gesture
private List<Vector2> touchPositions = new List<Vector2>();
void Update()
{
// Capture touch input
if (Input.touchCount > 0)
{
Vector2 touchPosition = Input.GetTouch(0).position;
touchPositions.Add(touchPosition);
}
// Check if we have enough touch points
if (touchPositions.Count >= minPointsForGesture)
{
// Fit a circle to the touch points
CircleFitResult circleFit = FitCircle(touchPositions);
// Check if the circle meets criteria for a circular gesture
if (circleFit.radius > minRadius)
{
Debug.Log("Circular gesture detected!");
}
}
}
CircleFitResult FitCircle(List<Vector2> points)
{
// Calculate centroid (average position)
Vector2 centroid = Vector2.zero;
foreach (Vector2 point in points)
{
centroid += point;
}
centroid /= points.Count;
// Estimate circle parameters (center and radius)
float radiusSum = 0f;
foreach (Vector2 point in points)
{
radiusSum += Vector2.Distance(point, centroid);
}
float estimatedRadius = radiusSum / points.Count;
return new CircleFitResult(centroid, estimatedRadius);
}
}
// Custom struct to hold circle fit results
public struct CircleFitResult
{
public Vector2 center;
public float radius;
public CircleFitResult(Vector2 center, float radius)
{
this.center = center;
this.radius = radius;
}
}
- The CircularGestureDetector script captures touch input and accumulates touch positions.
- When enough touch points are collected, it calls the FitCircle method to estimate the circle parameters (center and radius).
- The FitCircle method calculates the centroid and estimates the radius based on the average distance from the centroid.
- Finally, it checks if the estimated radius exceeds the minimum required radius for a circular gesture.
1 Like