Fără îndoială, în implementarea sa internă, clasa SimpleOrientationSensor se referă la un dispozitiv numit un accelerometru. Accelerometrul măsoară accelerarea și, la prima vedere, se pare că informațiile despre accelerația pe calculator nu sunt de folos. Cu toate acestea, de la cursul fizic al școlii (și mai precis din cea de-a doua lege a lui Newton), suntem familiarizați cu formula:
Forța este egală cu produsul masei prin accelerație. Orice obiect este afectat de gravitate. Cel mai adesea accelerometrul unui calculator măsoară gravitatea și răspunde la întrebarea principală: "Unde este partea de sus și unde este fundul?"
Cu accelerometrul, puteți lucra direct prin clasa Accelerometru. Pentru a obține o instanță a clasei Accelerometer, utilizați o metodă statică cu același nume ca și clasa SimpleOrientationSensor:
Dacă metoda Accelerometer.GetDefault revine nul, atunci calculatorul nu are un accelerometru, iar Windows 8 nu știe despre existența acestuia. Dacă aplicația dvs. nu funcționează corect fără un accelerometru, anunțați-l dacă lipseste.
În orice moment, puteți obține valoarea actuală a accelerometrului:
O metodă similară a clasei SimpleOrientationSensor se numește GetCurrentOrientation. Probabil, valoarea primită de la GetCurrentReading ar trebui verificată pentru null. Clasa AccelerometerReading definește patru proprietăți:
AccelerationX tip dublu
Accelerația tip dublu
AccelerationZ tip dublu
Marcator de timp de tip DateTimeOffset
Cele trei valori duble definesc în mod colectiv un vector tridimensional care indică direcția către Pământ în raport cu dispozitivul (vom vorbi mai curând despre acest lucru în detaliu).
De asemenea, puteți asocia un manipulator de evenimente cu obiectul Accelerometru:
Un eveniment SimpleOrientationSensor similar se numește OrientationChanged. La fel ca OrientationChanged, cititorul ReadChanged este executat într-un thread separat, deci, cel mai probabil, îl veți procesa astfel:
Clasa de AccelerometerReadingChangedEventArgs definește o proprietate numită tip Reading AccelerometerReading - la fel ca și obiectul returnat GetCurrentReading.
Cât de des ar trebui să aștept un apel la dispozitivul de procesare ReadingChanged? Dacă computerul este în stare de repaus, este posibil să nu fie apelat deloc! Din acest motiv, dacă trebuie să cunoașteți citirile inițiale ale accelerometrului, sunați la început de la GetCurrentReading.
În cazul în care se mută de calculator și își schimbă orientarea în spațiu, ReadingChanged handler este apelat atunci când valoarea (cu anumite criterii), dar nu mai mult decât intervalul în milisecunde, care este stocat în clasa proprietate ReportInterval Accelerometru. Valoarea mea implicită este 112; prin urmare, metoda ReadingChanged este numită de aproximativ nouă ori pe secundă.
Dacă doriți, puteți seta ReportInterval la o altă valoare, dar nu trebuie să fie mai mică decât valoarea returnată de proprietatea MinimumReportInterval. care pe calculatorul meu este de 16 milisecunde (de aproximativ 60 de ori pe secundă). Setați ReportInterval la MinimumReportInterval pentru a obține cantitatea maximă de date; setați proprietatea ReportInterval la zero pentru a reveni la valoarea implicită.
Restul clasei de senzori de la Windows.Devices.Sensors utilizează aceeași interfață de programare ca și accelerometrul. Toate acestea conțin următorii membri:
metoda statică GetDefault;
metoda instanței GetCurrentReading;
Proprietatea MinimumReportInterval, care este doar pentru citire;
Doar clasa SimpleOrientationSensor diferă de celelalte. Dacă computerul este staționar, proprietățile AccelerationX, AccelerationY și AccelerationZ ale clasei AccelerometerReading definesc un vector orientat către centrul Pământului. În înregistrarea vectorilor, coordonatele sunt de obicei afișate cu caractere aldine (x, y, z), astfel încât vectorul este diferit de punctul (x, y, z) în spațiul tridimensional. Un punct definește un anumit loc; vectorul definește direcția și modulul. Desigur, vectorii și puncte sunt conectate: direcția vectorului (x, y, z) este direcția de la punctul (0,0,0) la punctul (x, y, z) și vectorul unitar este lungimea acestui interval. Cu toate acestea, vectorul nu este un astfel de segment și nu se leagă de un anumit loc.
Modulul vectorului este calculat din forma tridimensională a teoremei pitagoreene:
Orice vector tridimensional există într-un sistem specific de coordonate tridimensional, iar vectorul obținut din obiectul AccelerometerReading nu face excepție. Pentru un comprimat cu o orientare de bază peisaj, acest sistem de coordonate este determinat de echipamentul dispozitivului:
Notă: coordonatele Y cresc de jos în sus - aceasta este direcția înapoi la cea utilizată în mod obișnuit atunci când lucrați cu grafică 2D. Direcția pozitivă Z este extrasă de pe ecran către utilizator. Acest sistem de coordonate este deseori numit "dreptaci"; Dacă trimiteți degetul arătător de la mâna dreaptă în direcția de valori pozitive ale lui X, iar media - în direcția de valori pozitive ale Y, atunci degetul mare va fi convertit la valori pozitive pe axa Z. Sau, dacă îndoiți degetele de la mâna dreaptă în direcția axei de valori pozitive Rotația X la valori pozitive axa F, degetul mare va indica spre valori pozitive ale Z. Acest aranjament este potrivit pentru orice pereche de axe în ordinea X, Y. Z: de exemplu, dacă îndoiți degetele de la mana dreapta pentru a roti de la axa Y pozitivă pentru a pune axa Z, atunci degetul mare se va confrunta cu valorile pozitive ale axei X.
În dispozitivele cu orientarea principală a cărților din punctul de vedere al utilizatorului, se utilizează același sistem de coordonate:
Un astfel de sistem de coordonate este rigid legat de echipamentul dispozitivului, iar vectorul Accelerometru se îndreaptă spre centrul Pământului față de acest sistem. De exemplu, atunci când tableta este ținută vertical în orientarea fixă, vectorul accelerație se confruntă într-o direcție - vector Y. Modul aproximativ egal cu 1, iar vectorul se deviază ușor de la (0, -1.0). Când dispozitivul se află pe o suprafață plană (de exemplu, pe o masă), ecranul este în sus, vectorul este în vecinătate (0,0, -1).
Modulul 1 înseamnă că vectorul este măsurat în unități de g - accelerația datorată gravitației pe suprafața Pământului (9,81 m / s 2). Pe Lună, modulul vectorului va fi de aproximativ 0,17. Trimiteți tableta într-o stare de cădere liberă (dacă nu vă pare rău) și modulul de vectorizare a accelerației va scădea la zero până când dispozitivul atinge solul.
Următorul program AccelerometerAndSimpleOrientation transmite date din clasele Accelerometru și SimpleOrientationSensor. Fișierul XAML conține un set de elemente TextBlock pentru etichete și date din fișierul de cod de fundal:
Fișierul de cod de fundal este ușor îmbunătățit comparativ cu cel precedent. Dacă nu puteți crea o instanță de accelerometru sau SimpleOrientationSensor, programul notifică utilizatorul. De asemenea, nu este de dorit ca accelerometrul să funcționeze într-un moment în care acesta nu este utilizat de program, deoarece descarcă bateria. Programul atribuie manipulanților în suprascrierea OnNavigatedTo și le deconectează de la OnNavigatedFrom. În alte privințe, structura codului diferă foarte puțin de programul precedent:
Iată cum arată programul pe tabletă:
Să nu vă deranjeze că modulul este puțin diferit de 1. Aceasta înseamnă că nu ați rupt accidental de pe suprafața Pământului, ci doar că accelerometrul nu este întotdeauna la fel de precis cum ne-am dori.
Atât coordonatele Y cât și Z sunt negative; aceasta înseamnă că tableta este ușor înclinată înapoi. Așa cum am menționat mai devreme, cu aranjamentul vertical al tabletei, vectorul ar trebui să fie teoretic (0, -1,0), iar dacă se află orizontal cu ecranul în sus, vectorul este teoretic egal cu (0,0, -1). Între aceste două poziții, tableta se rotește în jurul axei X. Apelând metoda Math.Atan2 cu valorile Y și Z, obțineți unghiul de rotație.
Rulați programul pe dispozitivul mobil, încercați să rotiți dispozitivul în diferite orientări și observați efectul. În mod obișnuit, datele SimpleOrientationSensor și Accelerometer sunt legate împreună după cum urmează:
Valorile senzorilor depind de rotirea dispozitivului
) trebuie interpretat foarte larg. Vectorii de accelerometru se schimbă destul de clar înainte de a ajunge la valoarea care determină modificarea SimpleOrientationSensor.
În plus, modificările constante ale orientării ecranului sunt uneori enervante. La fiecare schimbare, reîmprospătarea ecranului se oprește pentru scurt timp, iar conținutul se modifică în mărime. Probabil, de asemenea, veți ajunge la concluzia că programele care utilizează un accelerometru pentru a schimba conținutul ecranului ar trebui să blocheze și schimbarea automată a orientării.
Din acest motiv, în toate programele listate mai jos, există o comandă simplă în constructor care atribuie orientarea primară ca fiind cea preferată:
Dacă rulați programul AccelerometerAndSimpleOrientation pe dispozitivul dvs. mobil și mutați-l repede, direcția și modulul vectorului de accelerație se schimbă, de asemenea; vectorul nu înseamnă accelerarea 1g, orientată spre centrul Pământului. De exemplu, dacă trageți brusc dispozitivul spre stânga, vectorul de accelerare va fi direcționat spre dreapta - dar numai pentru timpul de accelerare a dispozitivului. Dacă reușiți să aliniați și să mențineți o viteză stabilă de mișcare, vectorul de accelerație "calmează" și din nou începe să îndrepte spre centrul Pământului. Opriți dispozitivul, iar modificarea vitezei va fi reflectată în vectorul de accelerare.
Una dintre aplicațiile standard ale accelerometrului este nivelul de spirit (nivelul de tâmplărie pentru verificarea suprafețelor orizontale). Fișierul XAML creează patru instanțe de Elipsă. Trei sunt folosite pentru a desena cercuri concentrice, iar al patrulea este un balon:
Fișierul de cod de fond stabilește proprietatea DisplayProperties.AutoRotationPreferences la DisplayProperties.NativeOrientation. Windows nu are niciun motiv să modifice automat orientarea ecranului. Programul utilizează, de asemenea, Handler-ul SizeChanged pentru a seta dimensiunile outerCircle și halfCircle:
Metoda SetBubble pare suspicios de simplă: este nevoie de componentele X și Y ale vectorului de accelerație și le folosește pentru a specifica coordonatele X și Y ale bulei centrale cu scalarea de-a lungul razei cercului exterior. Dar imaginați-vă că tableta este un ecran în sus sau în jos pe masă. Coordonata Z a vectorului de accelerație este egală cu 1 sau -1, iar ambele coordonate X și Y sunt zero, adică bubble-ul se află în centrul ecranului. Bine.
Acum întoarceți tableta astfel încât ecranul să fie perpendicular pe Pământ. Coordonata Z devine zero. Aceasta înseamnă că modulul vectorului de accelerare se calculează exclusiv din coordonatele X și Y:
Această ecuație descrie un cerc în plan; prin urmare, flaconul este undeva pe circumferința exterioară. Poziția sa specifică depinde de unghiul de rotație curent al tabletei față de axa Z.
Vectorul de accelerație este îndreptat spre centrul Pământului, iar bulele cresc în sus; aceasta înseamnă că pentru trecerea la coordonatele ecranului bidimensional trebuie să schimbăm semnele componentelor X și Y ale vectorului de accelerare. Dar, deoarece axa Y a vectorului de accelerație este deja inversată față de coordonatele ecranului, trebuie schimbată numai componenta X (ultimele două linii ale programului).
Iată cum arată programul pe tableta Microsoft Surface:
Desigur, ecranul nu oferă o idee despre mișcările haotice ale bulei! Citirile accelerometrului sunt foarte aproximative, iar într-o aplicație reală de deplasare este necesară o ușoară aplatizare. Vom face acest lucru în următoarele două programe!