Опубликован: 10.04.2013 | Уровень: для всех | Доступ: платный
Лекция 4:

Многоточечные жесты

< Лекция 3 || Лекция 4: 12345 || Лекция 5 >

Датчики

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

Датчики, опять же, это способ понять взаимоотношения устройства и физического мира, окружающего его, и их использование подразумевает ввод данных, так как вы, будучи человеком, можете влиять на эти взаимоотношения, в основном, перемещая устройство в пространстве или меняя их окружение. Датчики так же могут быть использованы как средства прямого ввода информации, вызывая перемещение объектов на экране, вместо использования какой-то формы абстрактного ввода данных наподобие мыши или клавиатуры. Например, вместо того, чтобы использовать абстрактное сочетание клавиш для того, чтобы наклонить игровое поле, вы можете, используя датчики, просто наклонить устройство. Встряхивание устройства, на самом деле, является хорошо известным физическим жестом, который может быть связан с командой вроде "Повтори, будь ты проклят! Почему ты не делаешь то, что я хочу?". Разве мы долгие годы не трясли наши компьютеры или не стучали по ним, когда они не делали то, что нам нужно? А компьютер с датчиками вполне может отреагировать на такое воздействие!

Вот, какую информацию могут нам сообщить различные датчики:

  • Местоположение (Location). Позиция устройства на Земле (мы обсудили это в предыдущем разделе).
  • Компас (Compass) и ориентация (Orientation). Ориентация устройства по отношению к магнитным полюсам Земли, или относительно нормального положения устройства (простая и сложная ориентация).
  • Инклинометр, креномер (Inclinometer). Предоставляет данные о поворотах устройства относительно поперечной, продольной и вертикальной осей в трехмерном пространстве.
  • Гирометр (Gyrometer). Данные об угловой скорости/вращательном движении устройства в трехмерном пространстве.
  • Акселерометр (Accelerometer). Ускорение устройства (в G) в трехмерном пространстве (X, Y, Z).
  • Окружающий свет (Ambient light). Яркость света в пространстве, окружающем устройство.

Эти датчики предоставляет API WinRT3Здесь присутствует и датчик для бесконтактного взаимодействий (proximity) близко расположенных устройств (NFC), который сообщает о том, что устройства находятся близко друг от друга или соприкасаются, но это больше средство для установления сетевого соединения, нежели датчик, похожий на другие. Мы рассмотрим его в лекции 15., некоторые из них созданы программным путем посредством синтеза датчиков (sensor fusion). Это подразумевает получение исходных данных от одного или большего коичества аппаратных датчиков, комбинирование, интерпретацию и представление их в виде, которым может воспользоваться приложение. Как и с указателями, вы можете пользоваться исходными данными, если нужно, но чаще в этом нет необходимости. Например, простой датчик ориентации (Simple Orientation) предоставляет простую интерпретацию расположения устройства по отношению к его расположению по умолчанию, округляя данные до 90-градусных секторов. Полный датчик ориентации, с другой стороны, комбинирует данные гирометра, акселерометра и компаса для того, чтобы предоставить матрицу трехмерной ориентации, которая гораздо более точна, но ориентирована (если можно использовать каламбур!) на более продвинутые сценарии, нежели обычное определение, расположено ли устройство вниз экраном или на боку.

Так как работа всех этих датчиков очень похожа друг на друга (это сделано специально, за исключением простого датчика ориентации, который не похож на другие), я хочу показать общий шаблон работы с API датчиков вместо детальных примеров для каждого из них. Подобные примеры можно найти среди SDK-примеров "Акселерометр" (http://code.msdn.microsoft.com/windowsapps/Accelerometer-Sensor-Sample-22982671), "Компас" (http://code.msdn.microsoft.com/windowsapps/Compass-Sensor-Sample-0ed09c55), "Гирометр" (http://code.msdn.microsoft.com/windowsapps/Gyrometer-Sensor-Sample-4fe891d9), "Инклинометр" (http://code.msdn.microsoft.com/windowsapps/Inclinometer-Sensor-Sample-0cd0bf84), "Датчик освещенности" (http://code.msdn.microsoft.com/windowsapps/LightSensor-Sample-4477824c) и "Датчик ориентации" (http://code.msdn.microsoft.com/windowsapps/OrientationSensor-sample-0b1732be).

Шаблон их использования выглядит следующим образом, некоторые особенности приведены в таблице ниже:

Получение объекта датчика посредством Windows.Devices.Sensors.<sensor>.getDefault().

Вызов метода getCurrentReading этого объекта для получения данных.

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

Таблица 4.7.
Название датчика (Windows.Devices.Sensors.) Дополнительные члены Тип возвращаемых данных (Windows.Devices.Sensors) Свойства возвращаемых данных (timestamp Имеет тип Date; остальные являются числами, если не указано иное)
Акселерометр (http://msdn.microsoft.com/library/windows/apps/windows.devices.sensors.accelerometer.aspx) Событие: shaken (аррументы события содержат лишь свойство timestamp) AccelerometerReading (http://msdn.microsoft.com/library/windows/apps/windows.devices.sensors.accelerometerreading.aspx) accelerationX (в G), accelerationY, accelerationZ, timestamp
Компас (http://msdn.microsoft.com/library/windows/apps/windows.devices.sensors.compass.aspx) n/a CompassReading (http://msdn.microsoft.com/library/windows/apps/windows.devices.sensors.compassreading.aspx) headingMagneticNorth (градусы), headingTrueNorth, timestamp
Гирометр (http://msdn.microsoft.com/library/windows/apps/windows.devices.sensors.gyrometer.aspx) n/a GyrometerReading (http://msdn.microsoft.com/library/windows/apps/windows.devices.sensors.gyrometerreading.aspx) angularVelocityX (градусы в секунду), angularVelocityY, angularVelocityZ, timestamp
Инклинометр (http://msdn.microsoft.com/library/windows/apps/windows.devices.sensors.inclinometer.aspx) n/a InclinometerReading (http://msdn.microsoft.com/library/windows/apps/windows.devices.sensors.inclinometerreading.aspx) pitchDegrees (градусы), rollDegrees (градусы), yawDegrees (градусы), timestamp
Датчик освещенности (http://msdn.microsoft.com/library/windows/apps/windows.devices.sensors.lightsensor.aspx) n/a LightSensorReading (http://msdn.microsoft.com/library/windows/apps/windows.devices.sensors.lightsensorreading.aspx) illuminenceInLux (люксы), timestamp
Датчик ориентации (http://msdn.microsoft.com/library/windows/apps/windows.devices.sensors.orientationsensor.aspx) n/a OrientationSensorReading (http://msdn.microsoft.com/library/windows/apps/windows.devices.sensors.orientationsensorreading.aspx) quaternion, (SensorQuaternion содержит свойства w, x, y, и z) rotationMatrix (Sensor-RotationMatrix содержит свойства m11, m12, m13, m21, m22, m23, m31, m32, m33), timestamp

Вот образец кода из примера "Гирометр" (js/scenario1.js):

gyrometer = Windows.Devices.Sensors.Gyrometer.getDefault();

var minimumReportInterval = gyrometer.minimumReportInterval;
var reportInterval = minimumReportInterval > 16 ? minimumReportInterval : 16;
gyrometer.reportInterval = reportInterval;

gyrometer.addEventListener("readingchanged", onDataChanged);   
// Не забудьте удалить при необходимости

function onDataChanged(e) {
var reading = e.reading;
document.getElementById("eventOutputX").innerHTML = reading.angularVelocityX.toFixed(2);
document.getElementById("eventOutputY").innerHTML = reading.angularVelocityY.toFixed(2);
document.getElementById("eventOutputZ").innerHTML = reading.angularVelocityZ.toFixed(2);
}	
 

В случае с датчиком ориентации, понятие кватернион (quaternion) легче всего понять как вращение точки [x,y,z] вокруг одной произвольной оси. В этом – отличие от матрицы вращения, которая представляет вращение по всем трем осям. Математическая основа кватернионов довольно экзотична, она включает в себя геометрические понятия комплексных чисел, математические понятия мнимых чисел, но работать с ними просто и фреймворки наподобие DirectX поддерживают их. Посмотрите пример "Сенсор ориентации" для того, чтобы больше узнать об этом.

Говоря об ориентации, я упоминал, что SimpleOrientationSensor (http://msdn.microsoft.com/library/windows/apps/windows.devices.sensors.simpleorientationsensor.aspx) работает немного не так, как остальные. Его цель – в предоставлении информации о квадранте (quadrant) ориентации, а не в предоставлении данных о точной ориентации устройства, и, возможно, это все, что вам нужно. Например, приложению для просмотра звездной карты нужно знать, расположено ли устройство вниз экраном, таким образом оно сможет настроить вывод данных (используя и показания компаса) для того, чтобы то, что оно отображает на экране, соответствовало бы виду неба.

В итоге, использование этого датчика выглядит так:

  • Вызовите Windows.Devices.Sensors.SimpleOrientation.getDefault для того, чтобы получить объект.
  • Вызовите getCurrentOrientation для того, чтобы получить результаты чтения данных.
  • Событие orientationChanged используется для последующего получения данных, где eventArgs содержит свойства orientation (результат чтения данных) и timestamp.
  • Свойство reading – это объект SimpleOrientation (http://msdn.microsoft.com/library/windows/apps/windows.devices.sensors.simpleorientation.aspx), который содержит следующие свойства:
    • notRotated ("portrait up", книжная-сверху), rotated90DegreesCounterclockwise ("landscape left" альбомная-слева), rotated180DegreesCounterclockwise ("portrait down" книжная-снизу), rotated270DegreesCounterclockwise ("landscape right" альбомная-справа). Обратите внимание на то, что все это не имеет никакого отношения к состояниям просмотра наподобие полноэкранного альбомного или полноэкранного портретного режимов просмотра.
    • faceup, facedown (лицевой сторонй вверх или вниз, только для планшентых устройств).

Демонстрацию использования этого датчика вы можете найти в примере "Простой датчик ориентации" (http://code.msdn.microsoft.com/windowsapps/SimpleOrientationSensor-d948ac62).

Что мы только что изучили

  • Сообщение: "Дизайн приложений, использующих мышь, касания, перо – без дополнительных усилий" соответствует истине, так как работа с указателями и жестами, поступающими от различных устройств, не требует делать различия между способами ввода.
  • Использование встроенных элементов управления – это самый простой способ обработки ввода, но вы так же можете непосредственно обрабатывать события MSPointer* и MSGesture*, если в этом есть необходимость. Так же вы можете передавать события MSPointer в пользовательское средство распознавания жестов (оно инициирует собственные события).
  • Язык касаний Windows 8 включает в себя касание, нажатие и удержание, прокрутку/сдвиг, скольжение по диагонали (для выделения), жесты сжатия-растяжения, вращение, жесты у краев экрана (от верхней, нижней и от боковых сторон). Касание обычно обрабатывается в событии click, в то время как другие требуют создания объекта MSGesture, связи этого объекта с указателем и обработку последовательностей событий MSGesture*, которая используется для реализации манипуляций и перемещения с инерцией.
  • У языка касаний есть эквиваленты, реализуемые с помощью мыши, пера и клавиатуры. В случае с мышью и пером нужно проделать не так много работы (например, передавать события мыши wheel в объект жеста). Поддержка клавиатуры должна быть реализована отдельно, она использует обычные события HTML/JavaScript.
  • Поддержка клавиатуры так же включает в себя соответствующую настройку для работы с программной (экранной) клавиатурой, которая появляется автоматически для полей ввода текста и других элементов, поддерживающих редактирование содержимого. Она автоматически настраивает свой внешний вид в зависимости от типа вводимых данных и смещает содержимое приложения вверх, если нужно, для того, чтобы не перекрыть клавиатурой элемент управления, в который нужно вводить текст. Приложение так же может обрабатывать события, связанные с экранной клавиатурой для предоставления большего удобства, чем в случае с автоматическим поведением системы.
  • API поддержки рукописного ввода предоставляет приложениям средства для записи, сохранения и вывода последовательностей штрихов, оставленных указателем, штрихи так же можно передать средству распознавания рукописного текста.
  • API определения местоположения в WinRT, так же, как похожее API HTML5, предоставляет приложениям доступ к GPS-данным, а так же – события, показывающие, что устройство пересекло ранее заданное пороговое значение в пространстве.
  • API WinRT предоставляеют множество датчиков, которые можно использовать для ввода данных в приложение. В дополнение к датчику определения местоположения, это компас, датчик ориентации, основанный на квадрантах простой датчик ориентации, инклинометр, гиромет, акселерометр и датчик окружающего освещения.
  • Большая часть сенсоров используется по одному и тому же шаблону: получить объект сенсора, получить текущий результат чтения данных и, возможно, прослушивать событие readingChanged. С ними легко работать, что оставляет большую часть сил на поиск креативных способов их применения!
< Лекция 3 || Лекция 4: 12345 || Лекция 5 >
Дмитрий Мельник
Дмитрий Мельник
Беларусь
Сергей Ширяев
Сергей Ширяев
Россия, г. Москва