ios實(shí)現(xiàn)簡單隨便移動(dòng)的AR功能
先上個(gè)最終的效果動(dòng)態(tài)圖,

1、首先我們要自定義一個(gè)相機(jī)界面,可以用AVCaptureSession來自定義,不需要其他按鈕,只有一個(gè)預(yù)覽的界面;
2、我們要畫一個(gè)簡單的雷達(dá)圖,可以用CGContextRef來簡單實(shí)現(xiàn),雷達(dá)圖用來顯示你跟你附近的用戶(物體)的距離,通過跟實(shí)際物體的經(jīng)緯度來算兩點(diǎn)之間的距離,通過一定的比例來映射到雷達(dá)圖上,兩點(diǎn)之間的距離計(jì)算公式如下:
//兩點(diǎn)的經(jīng)緯度計(jì)算距離
-(float) DistanceFromCoordinates:(CLLocationCoordinate2D) myDot other:(CLLocationCoordinate2D)otherDot
{
double EARTH_RADIUS = 6378137.0;
double radLat1 = (myDot.latitude * M_PI / 180.0);
double radLat2 = (otherDot.latitude * M_PI / 180.0);
double a = radLat1 - radLat2;
double b = (myDot.longitude - otherDot.longitude) * M_PI / 180.0;
double s = 22 * asin(sqrt(pow(sin(a / 2), 2)
+ cos(radLat1) * cos(radLat2)
* pow(sin(b / 2), 2)));
s = s * EARTH_RADIUS;
s = round(s * 10000) / 10000;
return s;
}
要算物體在雷達(dá)圖上的顯示位置,根據(jù)三角函數(shù),sinA=對邊/斜邊,cosA=鄰邊/斜邊,斜邊我們已經(jīng)有了,就是兩點(diǎn)之間的距離,那么我們就需要知道一個(gè)角度,才能算出一條邊,通過這條邊跟半徑的加減,就可以算出這個(gè)物體在雷達(dá)圖上的位置。所以我們先要算兩點(diǎn)的方位角,看下面的一張圖:

這個(gè)維基上的一張方位角的解釋圖,我們可以同通過tan2函數(shù)來計(jì)算,公式如下:
- (float)getHeadingForDirectionFromCoordinate:(CLLocationCoordinate2D)fromLoc toCoordinate:(CLLocationCoordinate2D)toLoc
{
float fLat = DegreesToRadians(fromLoc.latitude);
float fLng = DegreesToRadians(fromLoc.longitude);
float tLat = DegreesToRadians(toLoc.latitude);
float tLng = DegreesToRadians(toLoc.longitude);
float degree = RadiansToDegrees(atan2(sin(tLng-fLng)*cos(tLat), cos(fLat)*sin(tLat)-sin(fLat)*cos(tLat)*cos(tLng-fLng)));
if (degree >= 0) {
return degree;
} else {
return (360+degree);
}
}
3、要實(shí)現(xiàn)雷達(dá)圖跟隨手機(jī)旋轉(zhuǎn)而轉(zhuǎn)動(dòng),這里我們要用到指南針的原理,通過CLLocationManager管理類,里面有個(gè)CLHeading類,我們可以實(shí)現(xiàn)指南針,看這個(gè)類的結(jié)構(gòu):

里面有真北,磁北,還有磁力值在x,y,z三軸上的磁力值,不過當(dāng)我用到這三個(gè)值的時(shí)候,發(fā)現(xiàn)有問題,在前后移動(dòng)手機(jī)的時(shí)候,發(fā)現(xiàn)這個(gè)值變化有停頓,如果用這個(gè)值來實(shí)現(xiàn)移動(dòng)會(huì)導(dǎo)致不流暢,所以我又用了陀螺儀數(shù)據(jù),通過CMMotionManager這個(gè)管理類來獲取手機(jī)移動(dòng)擺動(dòng)的角度,用來計(jì)算手機(jī)前后移動(dòng)的時(shí)候,物體在手機(jī)界面上下的位置。
-(void) startMotion
{
if (![_mgr isDeviceMotionActive] && [_mgr isDeviceMotionAvailable])
{
//設(shè)置采樣間隔
_mgr.deviceMotionUpdateInterval = 0.1;
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[_mgr startDeviceMotionUpdatesToQueue:queue
withHandler:^(CMDeviceMotion * _Nullable motion,
NSError * _Nullable error) {
double gravityX = motion.gravity.x;
double gravityY = motion.gravity.y;
double gravityZ = motion.gravity.z;
if (gravityY<=0 && gravityY>=-1)
{
//獲取手機(jī)的傾斜角度(zTheta是手機(jī)與水平面的夾角, xyTheta是手機(jī)繞自身旋轉(zhuǎn)的角度):
zTheta = atan2(gravityZ,sqrtf(gravityX*gravityX+gravityY*gravityY))/M_PI*180.0;
}
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self updataPoint];
}];
//[self performSelectorOnMainThread:@selector(updataPoint) withObject:nil waitUntilDone:NO];
}];
}
}
4、通過計(jì)算角度區(qū)間來顯示手機(jī)上的物體顯示還隱藏,也就是說在雷達(dá)圖上的點(diǎn)進(jìn)入扇形可見的區(qū)域就顯示出物體并且移動(dòng),超出就隱藏起來。還有一點(diǎn),就是要算碰撞檢測的手機(jī)上物體與物體如果太多,就不能疊在一起,通過錯(cuò)位錯(cuò)開來,可以通過CGRectIntersectsRect來寫個(gè)算法檢測兩個(gè)矩形是否碰到了。
簡單說了下我實(shí)現(xiàn)的原理,當(dāng)然實(shí)際做的時(shí)候會(huì)遇到很多問題。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
iOS漸變圓環(huán)旋轉(zhuǎn)動(dòng)畫CAShapeLayer CAGradientLayer
這篇文章主要介紹了iOS漸變圓環(huán)旋轉(zhuǎn)動(dòng)畫CAShapeLayer CAGradientLayer的相關(guān)資料,需要的朋友可以參考下2016-09-09
iOS 仿微博客戶端紅包加載界面 XLDotLoading效果
這篇文章主要介紹了iOS 仿微博客戶端紅包加載界面 XLDotLoading,需要的朋友可以參考下2017-02-02
詳解iOS應(yīng)用中播放本地視頻以及選取本地音頻的組件用法
這里來為大家詳解iOS應(yīng)用中播放本地視頻以及選取本地音頻的組件用法,分別使用MPMoviePlayerControlle和MPMediaPickerController來實(shí)現(xiàn),兩個(gè)都是MediaPlayer.framework中的多媒體組件,所以我們放到一起來講.2016-06-06
iOS使用UIScorllView實(shí)現(xiàn)兩指縮放功能
兩指縮放功能不僅可以用UIPinchGestureRecognizer手勢來實(shí)現(xiàn),還能用UIScorllView來實(shí)現(xiàn),UIScrollView可以輕松的實(shí)現(xiàn)最大與最小縮放值,以及滾動(dòng)的效果,效果非常棒,具體實(shí)例代碼大家參考下本文吧2017-03-03
iOS10語音識(shí)別框架SpeechFramework應(yīng)用詳解
在iOS10系統(tǒng)了,apple開放了與語音識(shí)別相關(guān)的接口,開發(fā)者可以將其應(yīng)用到自己的App中,實(shí)現(xiàn)用戶通過語音進(jìn)行功能操作。 這篇文章主要介紹了iOS10語音識(shí)別框架SpeechFramework應(yīng)用,需要的朋友可以參考下2016-09-09
Framework中實(shí)現(xiàn)OC和Swift的混編方案
這篇文章主要為大家介紹了Framework中實(shí)現(xiàn)OC和Swift的混編方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01

