日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS传感器:利用磁力计完成一个AR场景应用

發布時間:2023/12/14 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS传感器:利用磁力计完成一个AR场景应用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前面咱們用了陀螺儀、加速傳感器做了一些好玩的效果,今天咱們就用用第三個傳感器--磁力計--來做一個AR的場景。說到AR這個詞,請大家不要噴我哈,并沒有用到WWDC剛出的ARKit。而且今天這個例子重點是學習使用磁力計,本質上來講和AR關系并不大。噱頭,就是個噱頭。。。。

磁力計跟前面的加速計、陀螺儀,都是用到了上次說的iOS當中的那個核心運動框架CoreMotion, 也都用了CMMotionManager。

完成后的效果,能看到在視頻輸出的下面會有一個隨著屏幕移動的天空星辰背景圖,同時屏幕左上角會實時打印當前的方向信息、地理信息。

1. 磁力計的介紹

磁強計指的是各種用于測量磁場的儀器,也稱磁力儀、高斯計。它可以感應地球的磁場,獲得方向信息。

1.1 應用場景

那顯而易見,典型的應用場景就是用在電子羅盤和導航上面。

之前看到過某個大神用磁力計簡直玩出了花兒,隔空抓牛的感覺。利用iPhone上磁力計、加速計和麥克風實現平面和三維上的磁鐵追蹤,并能實時的反饋在iPhone 屏幕上。

看上去屌炸了,有沒有?宅胖還專門找到了這篇文章的報道,有興趣的可以進去看看,里面有實現后的視頻。mobile.163.com/14/1127/09/…

1.2 需要了解的基本概念

要用到磁力計,經常會聽到有人說到“磁北”、“真北”這兩個高頻詞,CoreMotion也會給我們返回這兩個數值。是什么意思吶?

  • 真北:指的是地理的北極
  • 磁北:指的是磁場北極

納尼?這是什么鬼?來來來,咱們科普一下。

  • 磁北 磁北是以大地磁場為基準的,通過各種傳感器傳送的方位都是以磁北為基準的。BUT!!!!敲黑板!!!!!磁北的具體位置是隨著時間而改變的。 也就是說咱們隨著地球的旋轉,咱們除了有一年四季的變化、時間的變化,連磁場都會發生改變。嗯,是這樣的。

  • 真北 由于磁北是會變化的,那我們怎么用?不可能還要計算地球自轉軸、考慮時間因素吧。所以才有了真北這個概念。

  • 真北是地球自轉的地理北極,這個就是考慮到了各種因素,是一個固定的位置。所以咱們電子羅盤神馬的所指的北,說的是這個真北。通常情況下,方位都是需要矯正到真北的。蘋果很貼心啊,真北就不用自己算了,直接也會有返回的數值。

    剩下的還有磁偏角校正、網絡北、網絡北校正、收斂角等等學術概念。

    那豈不是電子羅盤上面的北和指南針上面的北不一致啊?

    問這個問題的童鞋那是相當的聰明呀,那肯定是不一致的。不過誤差也是在可感官接受的范圍內。在等會兒的例子里面,咱們把這兩個數值都打印出來,自己看看。

    2 . 磁力計的使用

    2.1 使用步驟

    磁力計同樣也是通過CoreMotion 這個框架來管理的,所以和前面兩個傳感器一樣,四個標準步驟:

    • 初始化CMMotionManager管理對象;
    • 調用管理對象的對象方法獲取數據;
    • 處理數據;
    • 當不需要使用的時候,停止獲取數據。

    2.2 磁力計數據獲取的兩種方法

    CoreMotion中有2種獲取數據方式,一種叫做PUSH的方式,一種叫做PULL的方式。顧名思義,PUSH就是被動的獲取。設定完了之后,線程定時把獲取到的數據推送回來。可想而知,對于資源的消耗是會稍微大一點的。PULL,就是要去索取。拉一下才會獲取到數據。不要不給。上一次代碼是Swift的,這一次咱們就使用OC啦。

    2.2.1 PULL的方式

    //PULL的方法獲取數據 - (void)pullMagnetometer {//? ??判斷磁力計是否可用if?(self.manager.magnetometerAvailable) {//? ? ? ??設置磁力計采樣頻率self.manager.magnetometerUpdateInterval?=?0.1;//開始更新,后臺線程開始運行。這是Pull方式。[self.manager?startMagnetometerUpdates];NSLog(@"X = %f,Y = %f,Z = %f",self.manager.magnetometerData.magneticField.x,self.manager.magnetometerData.magneticField.y,self.manager.magnetometerData.magneticField.z);}?else?{NSLog(@"It cannot be used!");} } 復制代碼

    2.2.2 PUSH的方式

    //PUSH的方法獲取數據 - (void)pushMagnetometer {//? ??判斷磁力計是否可用if?(self.manager.magnetometerAvailable) {//? ? ? ??設置磁力計采樣頻率self.manager.magnetometerUpdateInterval?=?0.1;//Push方式獲取和處理數據,這里我們一樣只是做了簡單的打印。把采樣的工作放在了主線程中。[self.manager?startMagnetometerUpdatesToQueue:[NSOperationQueue?mainQueue]?withHandler:^(CMMagnetometerData?*?_Nullable?magnetometerData,?NSError?*?_Nullable?error) {NSLog(@"X = %f,Y = %f,Z = %f",magnetometerData.magneticField.x,magnetometerData.magneticField.y,magnetometerData.magneticField.z);}];}?else?{NSLog(@"It cannot be used!");} } 復制代碼

    3. 開始我們的小案例

    寫這個案例的時候發現要實現一個比較逼真的AR,咱們有好多東東都沒有分享過。所以例子寫完之后,寫這篇文章的時候又對這個例子做了一些調整。大幅簡化刪減了了好多需求。但是,最后還是使用了相機、百度地圖,如果這兩個都不用,那真的一點都不能算是AR了。

    完成后的效果,能看到在視頻輸出的下面會有一個隨著屏幕移動的天空星辰背景圖,同時屏幕左上角會實時打印當前的方向信息、地理信息。

    小案例里面的相機不用緊張,咱們后面也還是會分享的。還有一個之前說過的,多線程也記得的哈,下一個系列就來補。

    3.1 思維導圖

    3.2 準備工作

    3.2.1 SDK的導入

    這個例子里面咱們用了百度地圖,所以需要導入百度地圖的SDK。因為咱們沒有分享過如何使用第三方庫,可以看看這篇文章iOS·采用第三方(百度地圖SDK)實現定位等功能開發

    3.2.2 相機、定位權限的索取

    iPhone對于APP使用用戶的隱私權限做了很嚴格的規定,每個APP使用用戶隱私之前必須要讓用戶知道并且同意。大概也正是因為這點,本宅胖才這么愛iPhone吧。雖然開發的時候就面臨著很多問題,但至少產品始終是站在用戶的角度考慮問題的。

    在Info.plist中向用戶索取相機和地理位置信息的權限。

    • Privacy - Camera Usage Description
    • Privacy - Location When In Use Usage Description

    麥克風、媒體庫的權限就不需要了。之前沒有刪減的那個案例里面用到了這個。說起來好心疼~~~

    3.2.3 相機使用

    相機在這個案例里面,使用的是AVFoundation框架。也是很心痛,這部分之前沒有分享過。所以如果等不及俺的分享,可以先看看這個。Objc的第21期內容:iOS上的相機捕捉

    別忘了在頭文件<AVFoundation/AVFoundation.h>,同時遵守代理協議AVCaptureVideoDataOutputSampleBufferDelegate。

    3.3 創建動態活動的星空背景

    從網上找到的星空圖是4000*2800的大小,要讓它完全超出屏幕。這樣才能根據手機的移動進行活動。

    同樣的,為了能夠明顯的看到效果,在從陀螺儀獲取到的數值之后,添加了一個放大倍數。這個小例子里面咱們使用的是5。

    3.3.1 使用陀螺儀進行防抖

    如果陀螺儀返回的數據在某個特定小范圍內,我們就是視同只是手抖,不對圖片本身進行處理。這樣就看不到背景圖片明顯抖動的感覺了。

    • 注意:陀螺儀返回的各軸旋轉角度是有可能為負數的,所以別忘了用絕對值進行判斷。
    //? ? ? ? ? ??做一下防抖動的處理,如果手機旋轉的不太大,就不執行操作 if?(fabs(gyroData.rotationRate.x) *?multiplier?<?0.2?&&?fabs(gyroData.rotationRate.y) *?multiplier?<?0.2) {return?; }復制代碼

    3.3.2 讓背景星空圖隨著屏幕進行運行

    直接修改背景圖的center就好了,讓原center添加上需要進行的位移量就可以實現了。 這里需要注意的是,需要對邊界值進行處理。如果屏幕旋轉的亂七八糟,我們要讓視頻輸出層下面始終有一個背景存在。

    ? ? ? ? ? ??//? ? ? ? ? ??因為背景圖的大小事屏幕寬度的三倍,高度的兩倍。為了防止超出邊界,進行限制if?(imageRotationX >?self.view.frame.size.width?*?1.5) {imageRotationX =?self.view.frame.size.width?*?1.5;}if(imageRotationX < (-?self.view.frame.size.width?*?0.5)){imageRotationX=(-?self.view.frame.size.width?*?0.5);}if?(imageRotationY >?self.view.frame.size.height) {imageRotationY =?self.view.frame.size.height;}if?(imageRotationY <?0) {imageRotationY =?0;}復制代碼

    3.4 利用百度地圖輸出磁力計信息、經緯度、高度

    3.4.1 輸出磁力計信息

    根據百度地圖SDK的文檔,在用戶的方向信息放生變化之后,會調用以下的方法。 這里我們沒有做任何特殊的處理,就只是簡單的打印出來了磁北、真北、三軸的偏移量。

    等會兒運行的時候大家就能看到之前的問題,到底磁北、真北之間相差多少。

    /***用戶方向更新后,會調用此函數*@param userLocation?新的用戶位置*/ - (void)didUpdateUserHeading:(BMKUserLocation?*)userLocation {self.magnetometerInfo.numberOfLines?=?0;self.magnetometerInfo.text?= [NSString?stringWithFormat:@"磁北:%.0f,真北:%.0f \n偏移:%.0f \nx:%.1f y:%.1f z:%.1f",userLocation.heading.magneticHeading,userLocation.heading.trueHeading,userLocation.heading.headingAccuracy,userLocation.heading.x,userLocation.heading.y,userLocation.heading.z]; }復制代碼

    3.4.2 輸出用戶位置信息:經緯度、高度

    /***用戶位置更新后,會調用此函數*@param userLocation?新的用戶位置*/ - (void)didUpdateBMKUserLocation:(BMKUserLocation?*)userLocation {self.physicalLocation.numberOfLines?=?0;self.physicalLocation.text?= [NSString?stringWithFormat:@"經度:%f \n緯度:%f \n高度:%f",userLocation.location.coordinate.longitude,userLocation.location.coordinate.latitude,userLocation.location.altitude]; }復制代碼

    源代碼下載地址:OC下載地址

    總結

    以上是生活随笔為你收集整理的iOS传感器:利用磁力计完成一个AR场景应用的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。