Отслеживание кругового движения мыши в OpenGL

Я работаю над реализацией простого средства просмотра сетки в C ++ с основными функциями, такими как перевод, вращение, масштабирование.
Я застрял с реализацией поворота объекта вдоль оси Z с помощью мыши. Я хочу реализовать следующее:

  1. Нажмите и перетащите мышь вертикально (подойдет почти вертикально, так как я использую простой порог для фильтрации незначительных отклонений по горизонтальной оси), чтобы повернуть объект по оси y (эта часть выполнена).
  2. Нажмите и перетащите мышь горизонтально, как описано выше, чтобы повернуть объект вдоль оси x (эта часть тоже сделана).
  3. Для вращения по оси Z я хочу обнаружить круговое (или вдоль дуги) движение мыши. Я застрял с этой частью, и не знаю, как это реализовать.

Для вышеупомянутых двух я просто использую atan2 (), чтобы определить угол движения. Но как мне обнаружить круговые движения?

3

Решение

Единственный способ справиться с этим — это задержка между пользователем, начинающим делать движение, и вращающимся объектом:

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

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

Чтобы начать, вот схема чрезвычайно плохого алгоритма:

По клику пользователя сохраняем координаты x и y.
Каждые 1/10 секунды хранят новые координаты и process_for_pattern.

в process_for_pattern вы ищете:

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

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

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

0

Другие решения

Возможно, вам следует определить область экрана (например, на границах окна), которая при нажатии будет инициировать движение дуги — или использовать какой-либо другой модификатор, кнопку или что-то еще.

Затем одним щелчком мыши вы фиксируете координаты и центр вращения (ось сетки) в 2D-пространстве экрана. Это дает вам вектор (центр сетки, кнопка вниз pos)

При каждом движении мыши вы вычисляете новый вектор (центр сетки, положение мыши), а угол между двумя векторами — это угол поворота.

0

Я не думаю, что это работает так …

Вы можете преобразовать вращение колеса мыши в ось z или использовать ориентацию камеры кватерниона, которая может вращаться вдоль каждой оси почти интуитивно …

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

0

Это не совсем то, что вы хотите, но должны подойти достаточно близко.

Выберите круговую область, в которой ваши движения, пронумерованные 1 и 2, работают так, как описано (на рисунке это будет область, которая меньше, чем красный круг. Однако, когда пользователь щелкает за пределами круговой области, вы сохраняете исходную позицию щелчка ( показано зеленым). Это определяет точку, которая имеет определенный угол относительно оси X вашего экрана (вы можете легко найти это с помощью некоторого триггера), а также определяет радиус круга, над которым работает пользователь ( (красный). Отпуск мыши добавляет вторую точку (синюю). Затем вы находите угол, который эта точка имеет относительно центра экрана и оси X (как и прежде). Затем вы проецируете этот угол на круг с радиусом, определяемым по первому щелчку. Темно-красная дуга определяет величину поворота модели.

введите описание изображения здесь

Этого должно быть достаточно, чтобы вы начали.

0

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

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

В качестве альтернативы вы можете использовать центр выбранной сетки, если ваше приложение работает так.

0

Вы не можете обнаружить движение «круговой вдоль дуги» мыши с точностью, близкой к точности, необходимой для просмотра 3d-модели. То, что вы хотите, это что-то вроде этого: http://thetechartist.com/?p=80

Вы назначаете ось (x, y или z), используя сочетания клавиш или индикаторы осей на экране, которые можно захватить с помощью мыши.

Это будет гораздо точнее, чем пытаться обнаружить жест «дуги». Любое распознавание «дуги» обязательно будет включать задержку, пока вы накапливаете достаточно образцов мыши, чтобы решить, начался ли жест дуги или нет. Такое распознавание жестов нетривиально (я сделал несколько жестов с помощью Wii-mote). Точно так же даже ваше простое «вертикальное» и «горизонтальное» обнаружение движения мыши потребует задержки по той же причине. Любой «простой порог для фильтрации незначительных отклонений» заставит его чувствовать себя подавленным и странным.

Для просмотра в формате 3D вам нужна чувствительность мыши 1: 1, а это означает просто явное назначение оси с помощью сочетания клавиш или пользовательского интерфейса и т. Д. Для поворота оси X просто ограничьте ее мышью x, осью y — мышью y, если хотите. Для z вы можете аналогичным образом ограничить ввод x или y мышью или просто взять общее пройденное расстояние 2d мыши. Это зависит от того, что вам нравится.

В качестве альтернативы, вы можете попробовать кодировать поддержку 3D-мыши, например 3dConnexion SpaceExplorer.

0
По вопросам рекламы [email protected]