Подтвердить что ты не робот

Простое обнаружение круговых жестов

Я смотрю простой, программный способ определения того, нарисовал ли пользователь круглую форму. Я работаю на C, но я счастлив работать с псевдокодом. Немного Googling вызывает много (надеюсь) чрезмерно сложных методов.

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

У меня есть основное представление о том, как это можно сделать:

Отслеживайте все движения, используя функцию опроса. Каждый раз, когда функция опроса, текущая позиция мыши сохраняется. Здесь мы просматриваем исторические данные о местоположении и делаем грубую "привязку к позиции" для сравнения двух местоположений. Если новое местоположение находится на достаточно близком расстоянии от старой позиции, мы удаляем все исторические данные перед старым местоположением.

Хотя это работает теоретически, это беспорядок на практике. У кого-нибудь есть предложения? Бонусные точки, если предложенный метод может определить, была ли она нарисована по часовой стрелке или против часовой стрелки.

4b9b3361

Ответ 1

Основываясь на вашей функции отслеживания/опроса, которая толкает пары float в стеке. Это необходимо сделать с регулярным интервалом времени.

  • Сделайте поиск по порогу для двух равных записей в списке. Теперь у вас есть два индекса в вашем стеке; первая и вторая равные записи. Рассмотрим это как строку.
  • Получить абсолютную разницу в показателях. Затем разделим на два и получим координаты этой точки. (Центр линии.)
  • У вас есть две точки: таким образом вы можете получить радиус круга, пройдя расстояние между двумя точками, разделенное на два.
  • Разделите число шагов 2 на 2, теперь у вас есть четверти.

    Если линия на шаге 1 вертикальна и первая точка линии находится наверху: если первая четверть оставлена ​​от центральной точки, кружок был направлен против часовой стрелки. Если первая четверть справа от центральной точки, кружок был направлен по часовой стрелке. Если первая точка линии находится внизу, обратная (т.е. Ccw = > cw и cw = > ccw)

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

  • Проверьте, был ли это круг: итерация по всем парам координат и вычисление расстояния до центральной точки. Измените порог допустимых расстояний от расчетного расстояния и фактическое расстояние до центральной точки.

На шагах 2 и 4 вы можете настроить этот алгоритм дальше, взяв среднее число из нескольких индексов, если интервал синхронизации очень низкий (быстрый опрос). Например: в массиве 30 пар, тогда вы получаете средние пары в 0, 1 и 28, 29, чтобы получить верхнюю точку. Сделайте то же самое для всех остальных точек.

Надеюсь, это достаточно легко.

Ответ 2

Ты определенно на правильном пути ИМХО. В основном вам нужно сравнить каждую точку мыши с предыдущей точкой мыши и вычислить угол между ними (как это предусмотрено на единичном круге, где первая точка находится в начале координат). Для этого вы можете использовать формулу:

double angle = atan2(y2 - y1, x2 - x1) * 180 / PI;

if (angle < 0)
    angle += 360;

То, что вы закончите, - это то, что для движения по часовой стрелке угол будет вращаться в положительном направлении, тогда как для движения против часовой стрелки угол будет вращаться в отрицательном направлении. Вы можете определить, является ли текущий угол больше или меньше предыдущего со следующей логикой:

if (angle2 > 270 && angle1 < 90)
{
    angle1 += 360
}
else if (angle1 > 270 && angle2 < 90)
{
    angle2 += 360
}

bool isPositive = (angle2-angle1 > 0);

Если вы получаете определенное количество векторов, все с увеличивающимися углами (isPositive является истинным, скажем, 10 раз), вы можете предположить, что кружок по часовой стрелке нарисован; если тенденция отрицательная (isPositive - ложь 10 раз), это против часовой стрелки.:)

Ответ 3

Не пробовал это, но идея пришла вам в голову, читая ваш вопрос, так что вы можете поделиться им с вами:

Я предполагаю, что круг должен быть нарисован в течение разумного промежутка времени, учитывая устойчивую "скорость выборки" мыши, которая оставила массив 2D-векторов (точек) известного размера. Добавьте их все и разделите на число 2D векторов, чтобы получить оценку "центральной" точки в массиве. Затем сформируйте векторы от этой центральной точки к точкам в массиве и сделайте точечные произведения (нормализующиеся по длине вектора), убедившись, что знак точечных произведений остается идентичным для диапазона точек, означает, что все точки движутся в одном и том же направление, положительный знак указывает на движение против часовой стрелки, отрицательное - как раз наоборот. Если накопленный угол превышает 2 PI, круговое движение было нарисовано.

Удачи.

Ответ 4

1 - Выберите любые 3 из пунктов

2 - Если точки коллинеарны + / - "некоторый буфер", то это не круг.

3 - Используйте метод, описанный в Википедии, для нахождения описанного круга для треangularьника, чтобы найти среднюю точку и радиус вашего круга-кандидата

Центр окружности треangularьника можно построить, нарисовав любые два из трех перпендикулярных биссектрис. Для трех неколлинеарных точек эти две линии не могут быть параллельными, а центр окружности - это точка где они пересекаются. Любая точка на биссектрисе равноудалена от две точки, которые он делит пополам, из чего следует, что эта точка, на оба биссектрисы равноудалены от всех трех вершин треangularьника. круговое излучение - это расстояние от него до любой из трех вершин.

4 - Проверьте расстояние до оставшихся точек. Если эти точки находятся в пределах "предполагаемого радиуса круга" + / - "некоторый буферный допуск", то это круг.

5 - Чтобы определить направление, просто рассчитайте angular между первой и второй точками от средней точки. Отрицательный angular правильный. Положительный angular остался. (Может быть изменено в зависимости от используемой вами системы координат)