Как получить градусы поворота для события мультитач двумя пальцами? - PullRequest
7 голосов
/ 15 июня 2011

У меня есть ImageView, который вы можете использовать для панорамирования одним пальцем или масштабирования двумя пальцами.Работает нормально.Я расширил его, чтобы обрабатывать вращение, и его поведение вызывает некоторую путаницу.

При возникновении события с несколькими касаниями вызывается этот метод, который должен возвращать угол поворота в градусах.Это не делает то, что я ожидаю.

private int fingersAngle(MotionEvent event)
{
    float x = event.getX(0) - event.getX(1);
    float y = event.getY(0) - event.getY(1);
    int degrees = (int)(Math.toDegrees(Math.atan2(y, x)));
    return degrees;
}

Когда я поверну два пальца, я ожидаю вывод, как ...

158 166 168 169 174 176 179 181 и т. Д.

Но то, что я на самом деле получаю, больше похоже на это:

158 166 -179 179 -179 179 -179

Кажется, проблема в знаках.Как этот метод узнает, является ли он 180 или -180, или 90 или -270?Изображение часто вращается в неправильном направлении, а затем внезапно прыгает и начинает вращаться в противоположном направлении.Еще хуже то, что направление, в котором он первоначально вращается, является практически случайным.

Я тестирую приложение с помощью Nexus One, но также вижу ту же проблему на планшете Advent Vega.Оба устройства работают нормально с Google Maps в 3D, чтобы повернуть экран (если иногда немного нервно), поэтому доказательства не предполагают аппаратных ограничений.

Вторая проблема заключается в том, что когда два пальца находятся приблизительно вертикально илиВыровненный по горизонтали угол просто не меняется, поэтому вращение «залипает» примерно на 10-20 градусов сверху / снизу / влево / вправо.

В настоящее время я проверяю, не изменился ли угол внезапноизменил огромное количество, и если это так, вычтите его из 360. Уродливо, черт возьми, но это немного помогает.

Надеюсь, один из вас видел это раньше и знает, как извлечь угловое вращение из мульти-сенсорный жест.

Некоторые вещи в Android настолько просты, что это удивительно, но такие вещи очень болезненны.

Ответы [ 4 ]

4 голосов
/ 16 июня 2011

Чтобы эта работа работала так, как ожидают пользователи, вы должны сохранять некоторое состояние.

Касательная к дуге покажет вам только угол между двумя точками - мгновенный снимок системы. Но вы выполняете анимацию - то, что происходит со временем.

Итак, я думаю, что вы находитесь на правильном пути со своим «уродливым» решением, которое пытается обнаружить большие изменения угла. То, что вы действительно должны отслеживать с течением времени, это положение каждого пальца.

Предположим, пользователь использует большой и указательный пальцы для жестов. Вы должны убедиться, что их цифры представлены последовательно, например, большой палец всегда представлен (x 0 , y 0 ), а указательный палец - (x 1 , y 1 ) ,

Вполне вероятно, что у устройства есть какое-то правило, как сообщается каждая координата. Например, возможно, он всегда сообщит верхнюю левую координату в слоте «0» события, а нижнюю правую координату в слоте «1». Но если пользователь перемещает большой палец из нижнего правого в верхний левый, вы должны убедиться, что вы по-прежнему рассматриваете его как (x 1 , y 1 ) в формуле угла даже если сейчас устройство сообщает об этом как (x 0 , y 0 ) в событии. В противном случае изображение будет быстро переворачиваться на 180 градусов назад и вперед.

Если устройство не отслеживает пальцы для вас, вам придется придумать эвристику для угадывания. Простое «какая из предыдущих координат ближе к текущей координате» было бы хорошим началом, но я мог видеть необходимость чего-то более причудливого, если разрешение событий плохое.

1 голос
/ 15 июня 2011

Я никогда не сталкивался с этой проблемой, но я предполагаю, что использование atan2 увеличивает ваши углы от -180 до + 180.

Но поворот, который вы хотите применить к своему изображению, должен быть от 0 до 360.

Самое простое решение, вероятно, состоит в том, чтобы добавить 180 к вашей переменной в градусах перед ее возвратом.

РЕДАКТИРОВАТЬ: Поскольку вы добавили в комментарии, что это связано со случайностью, я думаю, что в зависимости от устройства, с которым вы работаете, вы можете столкнуться с печально известной ошибкой HTC Touch (и других ранних) мультитач: http://www.youtube.com/watch?v=Ds5qZ_3XRzI Это показывает это для Nexus One, но у героя и некоторых Motorola были те же проблемы.

0 голосов
/ 15 июня 2011

Проверьте, можете ли вы читать 2 пункта одновременно и полностью независимо. Я не уверен, что Nexus One делает. Проверьте эту страницу:

http://developer.android.com/reference/android/content/pm/PackageManager.html

и выясните, поддерживает ли ваше целевое устройство только FEATURE_TOUCHSCREEN_MULTITOUCH или лучше (то есть FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT). Вероятно, проще всего просто установить тестовое приложение - я думаю, что я использовал «мультитач видимый тест».

Если вашего устройства нет, то нет исправления или обходного пути. Это ограничение для водителя, обычно вызванное дурацким выбором сенсорных экранов со стороны производителей с ограниченным тиражом.

0 голосов
/ 15 июня 2011

atan2 () возвращает значение в диапазоне (-180 .. + 180).

Учитывая это, похоже, теперь он работает правильно?

(если вы находитесь на +179 градусов, то поворот на три градуса будет +182; но это обозначается как -178)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...