1. 程式人生 > >ios 簡單模仿隨便走的AR功能一

ios 簡單模仿隨便走的AR功能一

好久沒寫部落格了,把最近的一些研究寫下來,大笑

先來張隨便走的截圖,如下:


目前也有一些第三方的AR框架,所以不知道隨便走到底是基於第三方的還是自己做的,但接下來我們會用簡單的方式來實現AR功能。在這之前,你得先了解一些基本的常識,

1、 真北指的是地理的北極

2、磁北 磁北指的是磁場北極

3、方位角是從某點的指北方向線起,依順時針方向到目標方向線之間的水平夾角

我們知道在ios系統框架中,有一個叫CoreLocation框架,專門是跟定位有關,通過這個框架,我們可以很方便的實現指南針的功能。我們可以看下CLLocationManager這個管理類,裡面有經緯度、裝置的真實方向等資訊。我們看下

CLHeading這個類,如下:


通過這個類,我們可以獲取到裝置跟磁北、真北的角度,x,y,z方向上的磁力值,我們先簡單實現一個這樣的功能,先畫一個雷達圖,在雷達圖上有一根線指向磁北,

1、我們先新建一個UIVew,在drawRect:(CGRect)rec函式裡畫一個黑色的圓圈,程式碼如下:

- (void)drawRect:(CGRect)rect{
    
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGContextAddEllipseInRect(context, rect);
    [[UIColor colorWithRed:0 green:0 blue:0 alpha:0.6f] set];
    CGContextFillPath(context);
    
}
2、我們在黑色的圓圈上面畫一圈圈的白色圓圈,畫三次,程式碼如下:
    NSArray *colors = @[
                        [UIColor colorWithRed:240.0/255.0 green:240.0/255.0 blue:240.0/255.0 alpha:0.8],
                        [UIColor colorWithRed:240.0/255.0 green:240.0/255.0 blue:240.0/255.0 alpha:0.8],
                        [UIColor colorWithRed:240.0/255.0 green:240.0/255.0 blue:240.0/255.0 alpha:0.8]

                        ];
    
    NSInteger radius = self.frame.size.width/2/3, increment = self.frame.size.width/2/3;
    
    NSArray *angles = @[
                        @{@"start":@0, @"end":@360},
                        @{@"start":@0, @"end":@360},
                       @{@"start":@0, @"end":@360},
                        ];
    for (int i = 0; i < colors.count; i++) {

        [colors[i] setStroke];

        UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.frame.size.width/2, self.frame.size.height/2)
                                                         radius:radius
                                                     startAngle:DEGREES_TO_RADIANS([[angles[i] valueForKey:@"start"] integerValue])
                                                       endAngle:DEGREES_TO_RADIANS([[angles[i] valueForKey:@"end"] integerValue])
                                                      clockwise:YES];
        path.lineWidth = 1;
        
        [path stroke];
        
        if (i==colors.count-2)
        {
            increment=self.frame.size.width/2/3;
            
        }

        radius += increment;
        
        
       
    }

效果如下圖:


3、然後我們畫一根線,程式碼如下:
    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetLineWidth(context, 1);  //線寬
    CGContextSetAllowsAntialiasing(context, true);
    CGContextSetRGBStrokeColor(context, 70.0 / 255.0, 241.0 / 255.0, 241.0 / 255.0, 1.0);  //線的顏色
    CGContextBeginPath(context);
    CGContextMoveToPoint(context, self.frame.size.width/2, 0);
    CGContextAddLineToPoint(context, self.frame.size.width/2, self.frame.size.height/2);
    CGContextStrokePath(context);
4、我們初始化CLLocationManager這個類,程式碼如下:
 self.locationManager = [[CLLocationManager alloc] init];
        if ([CLLocationManager locationServicesEnabled])
        {
            // Configure and start the LocationManager instance
            self.locationManager.delegate = self;
            self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
            self.locationManager.distanceFilter = 100.0f;
            
//            [self.locationManager startUpdatingLocation];
//            [self.locationManager startUpdatingHeading];
        }
5、在CLLocationManager回撥函式裡,
- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
    
}
我們讓這個雷達圖跟著角度轉,指向磁北或真北,程式碼如下:
float direction = newHeading.trueHeading;
    
float headingAngle = -(direction*M_PI/180);
    
_arcsView.transform = CGAffineTransformMakeRotation(angle);
效果如下:


下篇文章,我們會繼續畫雷達圖,一個扇形區域,還有雷達圖上的點,大笑大笑大笑大笑

簡書地址,http://www.jianshu.com/users/affac8cd1e02/timeline

大家可以關注,喜歡寫文章的也可以關注我的專題,