2011-10-12 2 views
14

제스처 빌더를 사용하여 제스처 라이브러리를 만드는 내 앱에서 제스처 인식을 구현하고 있습니다. 제스처의 여러 변형을 사용하면 인식 (또는 성능)을 저해하거나 방해 할 수 있을지 궁금합니다. 예를 들어 원형 제스처를 인식하고 싶습니다. 나는 시계 방향으로 원을 그리는 것과 시계 반대 방향으로 하나씩 같은 의미 론적 의미를 갖는 적어도 두 가지 변주를 가질 것입니다. 그래서 사용자는 그것에 대해 생각할 필요가 없습니다. 그러나 각 방향, 예를 들어 다양한 반지름, 또는 다른 각도 회전을 포함하여 달걀 모양, 타원형 등과 같이 "충분히 가깝다"는 다른 모양의 여러 제스처를 저장하는 것이 바람직한 지 궁금합니다. 각각의 누구도이 경험이 있습니까?제스처 라이브러리에서 제스처의 변형을 사용하면 인식이 향상됩니까?

답변

19

좋아요, 안드로이드 소스에 대한 약간의 실험과 독서 후, 나는 조금 배웠습니다 ... 첫째, 다른 각도를 다루기 위해 제스처 라이브러리에서 다른 제스처를 만드는 것에 대해 반드시 염려 할 필요는없는 것처럼 보입니다. 회전 또는 내 원형 제스처의 방향 (시계 방향/반 시계 방향). 기본적으로 GestureStore는 SEQUENCE_SENSITIVE의 시퀀스 유형 (시작점과 끝점이 중요 함을 의미)과 오리엔테이션 스타일 인 ORIENTATION_SENSITIVE (회전 각이 중요 함)를 사용합니다. 그러나 이러한 기본값은 'setOrientationStyle (ORIENTATION_INVARIANT)'및 setSequenceType (SEQUENCE_INVARIANT)으로 재정의 될 수 있습니다.

소스의 주석을 인용하려면 ... "SEQUENCE_SENSITIVE가 사용되는 경우 현재 단일 스트로크 제스처 만 허용됩니다"및 "ORIENTATION_SENSITIVE 및 ORIENTATION_INVARIANT는 SEQUENCE_SENSITIVE 제스처에만 해당됩니다".

흥미롭게도 ORIENTATION_SENSITIVE는 단순히 "오리엔테이션 문제"이상을 의미하는 것으로 보입니다. 값은 2이며, 관련 주석 (일부분은 문서화되지 않은)은 다른 수준의 민감도를 요청할 수 있음을 의미합니다. 일부 계산을 수행 그러자 GestureLibary.recognize() 배향 형 값 호출 중에

// at most 2 directions can be recognized 
public static final int ORIENTATION_SENSITIVE = 2; 
// at most 4 directions can be recognized 
static final int ORIENTATION_SENSITIVE_4 = 4; 
// at most 8 directions can be recognized 
static final int ORIENTATION_SENSITIVE_8 = 8; 

(1, 2, 4, 8), 파라미터 numOrientations로 GestureUtils.minimumCosineDistance()로 통과 저의 급여 등급보다 높습니다 (아래 참조). 누군가가 이것을 설명 할 수 있다면, 나는 흥미 롭다. 두 제스처 간의 각도 차이를 계산한다는 것을 알았지 만 numOrientations 매개 변수를 사용하는 방식을 이해하지 못합니다. 내 기대 값은 2의 값을 지정하면 제스처 A와 제스처 B의 두 변형 사이의 최소 거리를 찾습니다. 한 변형은 "일반 B"이고 다른 하나는 180도 회전합니다. 따라서, 8의 값이 45도 간격으로 떨어진 8 개의 B 변이를 고려할 것으로 기대합니다. 그러나 아래의 수학을 완전히 이해하지는 못했지만 numOrientations 값 4 또는 8이 어떤 계산에서도 직접 사용되는 것처럼 보이지는 않지만 2보다 큰 값은 고유 한 코드 경로가됩니다. 어쩌면 그것 때문에 다른 값들이 문서화되지 않은 이유 일 수 있습니다.

/** 
* Calculates the "minimum" cosine distance between two instances. 
* 
* @param vector1 
* @param vector2 
* @param numOrientations the maximum number of orientation allowed 
* @return the distance between the two instances (between 0 and Math.PI) 
*/ 
static float minimumCosineDistance(float[] vector1, float[] vector2, int numOrientations) { 
    final int len = vector1.length; 
    float a = 0; 
    float b = 0; 
    for (int i = 0; i < len; i += 2) { 
     a += vector1[i] * vector2[i] + vector1[i + 1] * vector2[i + 1]; 
     b += vector1[i] * vector2[i + 1] - vector1[i + 1] * vector2[i]; 
    } 
    if (a != 0) { 
     final float tan = b/a; 
     final double angle = Math.atan(tan); 
     if (numOrientations > 2 && Math.abs(angle) >= Math.PI/numOrientations) { 
      return (float) Math.acos(a); 
     } else { 
      final double cosine = Math.cos(angle); 
      final double sine = cosine * tan; 
      return (float) Math.acos(a * cosine + b * sine); 
     } 
    } else { 
     return (float) Math.PI/2; 
    } 
} 

내 독서를 바탕으로, 나는 가장 간단하고 가장 좋은 방법은 불변의 순서 유형과 방향을 설정 한 저장 원형 제스처를 가질 것이라고 이론화. 그렇게하면 방향이나 방향에 관계없이 원형이 잘 일치해야합니다. 그래서 시도해 보았습니다. 원을 그리 듯이 원격으로 닮은 거의 모든 것에 대해 높은 점수 (약 25 ~ 70 범위)를 반환했습니다. 그러나 원형 (수평선, V 자형 등)에도 가까웠 던 제스처에 대해서는 20 점 정도의 점수를 보냈습니다. 그래서, 나는 일치해야하는 것과 그렇지 말아야 할 것 사이의 분리에 대해 기분이 좋지 않았습니다. 가장 잘 작동하는 것으로 보이는 것은 두 방향으로 저장된 두 개의 제스처를 사용하고 ORIENTATION_INVARIANT와 함께 SEQUENCE_SENSITIVE를 사용하는 것입니다. 막연한 원형에 대해서는 2.5 점 이상의 점수를 얻었지만 원형이 아닌 제스처에 대해서는 점수가 1 점 미만 (또는 전혀 일치하지 않음)입니다.

+2

또한 내 실험에서 다양한 반지름의 그려진 제스처와 좋은 일치를 얻기 위해 다른 반지름의 원형 제스처를 제스처 라이브러리에 저장할 필요가 없음을 발견했습니다. 즉 화면에서 그린 원형 동작 동일한 반향 제스처와 똑같이 잘 맞는 (즉, 비슷한 점수를 가졌음) 퍼포먼스와 관련해서는 타이밍을 정하지 않았지만 코드를 살펴보면 퍼포먼스는 라이브러리의 제스처 수에 비례하여 거의 선형적인 것으로 생각된다. –

+2

여기 팁 : setSequenceType (GestureStore.SEQUENCE_INVARIANT)를 호출하면 load()를 호출하기 전에 수행해야합니다. 그렇지 않으면 일치하는 항목이 전혀 없다는 것을 알 수 있습니다. –

+0

고맙습니다. 추가 방향 감도 수준을 사용하여 비슷한 스트로크와 제스처를 가졌지 만 다른 회전이있는 고정 된 문제가있었습니다. 이 설정을 사용하기 전에 더하기 및 균등 한 제스처가 충돌했습니다. – Ehz

관련 문제