IOS 特定于设备的开发:Core Motion基础

Core Motion框架集中了运动数据处理。该框架是在IOS 4 SDK中引入的,用于取代accelerometer加速计访问。它提供了对3个关键的机载传感器的集中式监测。这些传感器有陀螺仪、磁力计和加速计组成,其中陀螺仪用于测量设备的旋转,磁力计提供了一种测量罗盘方位的方式,加速计用于监测沿着3根轴的重力变化。第四个入口点称为设备移动(device motion),他把全部3中传感器都结合进单个监测系统中。

Core Motion使用来自这些传感器原始值创建可度的测量结果,主要表现为力向量的形式。可测量的项包括以下属性:

 》设备姿势(attitude):设备相对于某个参照画面的方向。姿势被表示为摇晃,前倾和左右摇摆的角度,他们都以弧度为单位。

》旋转速率(rotationRate):设备围绕它的三根轴中的每一根轴旋转的速率。旋转包括x、y和z角速度值,他们以弧度/秒为单位。

》重力(gravity):设备当前的加速度向量,由正常的重力场提供。重力的单位是g‘s,分别沿着x、y和z轴来测量。每个单位代表由地球提供的标准重力加速度(9.8米/秒的平方)

》用户加速度(userAcceleration):用户提供的加度素向量。像重力一样,用户加速度的单位也是g‘s,分别沿着x、y和z轴来测量。当把它们加到一起时,用户向量和重力向量代表给设备提供的总加速度。

 》磁场(magneticField):代表设备临近区域的总磁场的向量。磁场是沿着x,y和z轴以为特斯拉(microtesla)为单位测量的。还提供了校准精度,通知应用程序有关磁场测量的质量。

1.测试传感器

你可以使用在Info.plist中设置使用或排除机载传感器,也可以在程序中来测试每种可能的Core Motion支持:

@property (nonatomic , strong)CMMotionManager *motionManager;

 _motionManager = [[CMMotionManager alloc]init];
    //监测陀螺仪
    if(_motionManager.gyroAvailable)
    {
        [_motionManager startGyroUpdates];
    }

    //监测磁力计
    if(_motionManager.magnetometerAvailable)
    {
        [_motionManager startMagnetometerUpdates];
    }

    //监测重力感应器
    if(_motionManager.accelerometerAvailable)
    {
        [_motionManager startAccelerometerUpdates];
    }

    //监测Device Motion
    if(_motionManager.deviceMotionAvailable)
    {
        [_motionManager startDeviceMotionUpdates];
    }

开始更新不会产生像使用UIAccelerometer时遇到的委托回调机制。作为替代,你将负责轮询每个值,或者可以使用基于块的更新机制,执行在每次更新时提供的一个块(例如,startAccelerometerUpdatesToQueue:withHandler:).

2.使用Core motion做加速计蝴蝶飞的程序如下

@implementation TestBedViewController
{
    UIImageView *butterfly;

    float xaccel;
    float xvelocity;
    float yaccel;
    float yvelocity;

    float mostRecentAngle;

    CMMotionManager *motionManager;
    NSTimer *timer;
}

- (void) tick
{
    butterfly.transform = CGAffineTransformIdentity;

    // Move the butterfly according to the current velocity vector
    CGRect rect = CGRectOffset(butterfly.frame, xvelocity, 0.0f);
    if (CGRectContainsRect(self.view.bounds, rect))
        butterfly.frame = rect;

    rect = CGRectOffset(butterfly.frame, 0.0f, yvelocity);
    if (CGRectContainsRect(self.view.bounds, rect))
        butterfly.frame = rect;

    butterfly.transform = CGAffineTransformMakeRotation(mostRecentAngle + M_PI_2);
}

- (void) shutDownMotionManager
{
    NSLog(@"Shutting down motion manager");
    [motionManager stopAccelerometerUpdates];
    motionManager = nil;

    [timer invalidate];
    timer = nil;
}

- (void) establishMotionManager
{
    if (motionManager)
        [self shutDownMotionManager];

    NSLog(@"Establishing motion manager");

    // Establish the motion manager
    motionManager = [[CMMotionManager alloc] init];
    if (motionManager.accelerometerAvailable)
        [motionManager
         startAccelerometerUpdatesToQueue:[[NSOperationQueue alloc] init]
         withHandler:^(CMAccelerometerData *data, NSError *error)
         {
             // extract the acceleration components
             float xx = -data.acceleration.x;
             float yy = data.acceleration.y;
             mostRecentAngle = atan2(yy, xx);

             // Has the direction changed?
             float accelDirX = SIGN(xvelocity) * -1.0f;
             float newDirX = SIGN(xx);
             float accelDirY = SIGN(yvelocity) * -1.0f;
             float newDirY = SIGN(yy);

             // Accelerate. To increase viscosity lower the additive value
             if (accelDirX == newDirX) xaccel = (abs(xaccel) + 0.85f) * SIGN(xaccel);
             if (accelDirY == newDirY) yaccel = (abs(yaccel) + 0.85f) * SIGN(yaccel);

             // Apply acceleration changes to the current velocity
             xvelocity = -xaccel * xx;
             yvelocity = -yaccel * yy;
         }];

    // Start the physics timer
    timer = [NSTimer scheduledTimerWithTimeInterval: 0.03f target: self selector: @selector(tick) userInfo: nil repeats: YES];
}

- (void) initButterfly
{
    CGSize size;

    // Load the animation cells
    NSMutableArray *butterflies = [NSMutableArray array];
    for (int i = 1; i <= 17; i++)
    {
        NSString *fileName = [NSString stringWithFormat:@"bf_%d.png", i];
        UIImage *image = [UIImage imageNamed:fileName];
        size = image.size;
        [butterflies addObject:image];
    }

    // Begin the animation
    butterfly = [[UIImageView alloc] initWithFrame:(CGRect){.size=size}];
    [butterfly setAnimationImages:butterflies];
    butterfly.animationDuration = 0.75f;
    [butterfly startAnimating];

    // Set the butterfly‘s initial speed and acceleration
    xaccel = 2.0f;
    yaccel = 2.0f;
    xvelocity = 0.0f;
    yvelocity = 0.0f;

    // Add the butterfly
    butterfly.center = RECTCENTER(self.view.bounds);
    [self.view addSubview:butterfly];
}

- (void) loadView
{
    [super loadView];
    self.view.backgroundColor = [UIColor whiteColor];
    [self initButterfly];
}
时间: 2024-10-30 03:46:37

IOS 特定于设备的开发:Core Motion基础的相关文章

IOS 特定于设备的开发:UIDevice

UIDevice类展示了一些关键的特定于设备的属性,包括使用的iPhone ,Ipad或iPod Touch型号.设备名称.以及OS名称和版本. 他是一种一站式解决方案,用于提取出某些系统详细信息.每个方法都是一个实例方法,他们是使用UIDevice单例通过[UIDevice currentDevice]调用的. 可以通过UIDevice获取的系统信息包括下面的这些项. 1.systemName:它用于返回当前使用的操作系统的名称.对于目前这一代IOS设备,在平台上只运行一种OS:iPhone

IOS 特定于设备的开发:Info.plist属性列表的设置

应用程序的Info.plist属性列表使你能够在向iTunes提交应用程序时指定应用程序的要求.这些限制允许告诉iTunes应用程序需要哪些设备特性. 每个IOS单元都会提供一个独特的特性集.一些设备回提供照相机和GPS能力,另外一些则不会.一些设备具有机载陀螺仪.自动聚焦,以及其他强大的选项.你可以指定在设备上运行应用程序时需要哪些特性. 在Info.plist文件中包括UIRequiredDeviceCapabilities键时,iTunes将限制把应用程序安装到提供必须能力的设备.把这个列

IOS 特定于设备的开发:处理基本方向

UIDevice类使用内置的orientation属性获取设备的物理方向.IOS设备支持这个属性的7个可能的值. >UIDeviceOrientationUnknown:方向目前未知. >UIDeviceOrientationPortrait:Home键在下.   >UIDeviceOrientationPortraitUpsideDown:Home键在上 >UIDeviceOrientationLandscapeLeft:Home键在左边 >UIDeviceOrientat

IOS 特定于设备的开发:获取和使用设备姿势(通过手机方向控制3d物体显示)

利用设备的机载陀螺仪可以实现,当你旋转手机屏幕时,里面的画面不会随着视图更新而移动,以平衡物理运动. 下面例子利用少量简单的几何变换执行该操作.他建立一个运动管理器,订阅设备运动更新,然后基于运动管理器返回的摇晃,前倾和左右摇摆的角度应用图像变换. @implementation TestBedViewController { CMMotionManager *motionManager; UIImageView *imageView; } - (void) shutDownMotionMana

IOS 特定于设备的开发:基于加速计的滚动视图

倾斜滚轮使用设备的内置加速计来控制在UIScrollView的内容周围移动.当用户调增设备时,材料会相应的下落,他不会把视图定位在屏幕上,而是把内容视图滚动到一个新的偏移位置. 创建这个界面的挑战在于:确定设备在什么地方应该具有他的静止轴,大多数人最初建议当显示屏靠在他的背部应该是稳定的,并且z轴方向笔直的指向上方.事实证明:这实际是一个相当糟糕的设计选择.要使用那根轴,就意味着导航期间屏幕必须实际的偏离观看者.随着设备旋转离开视图,用户将不能完全看到屏幕上所发生的事情,尤其是在固定的位置使用设

IOS 特定于设备的开发:监测Retina支持

近年来,Apple在其旗舰设备上引入了Retina显示屏.根据Apple的说法,他的像素密度非常高,足以使人眼无法区分单独的像素. UIScreen类提供了一种容易的方式,用于监查当前设备是否提供了内置的Retina显示屏.检查屏幕的scale属性,它提供了从逻辑坐标空间转换为设备坐标空间的转换因子.对于标准显示屏,转换因子是1.0,因此1点对应于1个像素.对于Retina显示屏,它是2.0. -(BOOL)hasRetinaDisplay { return ([UIScreen mainScr

IOS 特定于设备的开发:使用加速器启动屏幕上的对象

借助一点编程工作,iPhone的机载加速计就可以使对象在屏幕上四处“移动”,实时响应用户倾斜手机的方式.下面的代码就是创建一个动画式的蝴蝶,用户可以使之快速移过屏幕. 使之工作的秘密在于:向程序中添加一个所谓的"物理计时器“.他不是直接响应加速中的变化,而是加速计回调用于测量当前的力.它取决于计时器例程随着 时间的推移通过改变他的画面对蝴蝶应用那些力.下面是列出要记住的关键点. (1).只要力的方向仍然保持相同,蝴蝶就会加速.他的速度会依据加速力在x或y方向上的量度成比例的提高. (2).由计时

IOS 特定于设备的开发:获取额外的设备信息

sysctl()和sysctlbyname()允许获取系统信息.这些标准的UNIX函数用于询问操作系统有关硬件和OS的详细信息. 这些常量使你能够检查核心信息,比如系统的CPU频率,可用的内存量等.它引入了一个UIDevice类,用于搜集系统信息,并通过一系列方法调用返回它. 每个型号都提供了独特的内置能力,准确知道你正在处理哪款iPhone有助于确定那个单元是否有可能支持诸如可访问性,GPS和磁力计之类的特性. #pragma mark sysctlbyname utils - (NSStri

IOS 特定于设备的开发:检查设备接近度和电池状态

UIDevice类提供了一些API,使你能够跟踪设备的特征,包括电池的状态和接近度传感器.他们二者都以通知的形式提供更新,可以订阅他们,以便在有重要的更新时通知你的应用程序. 1>启动和禁用接近度传感器 接近度在此时是一个特定于iPhone的特性.iPod Touch和iPad没有提供接近度传感器.除非具有相对身体部位握持iPhone的某个迫切的理由(或者反之亦然),否则使用接近度传感器获益甚少. 当启用接近度感应器时,它具有一项主要的任务.他会检测正前方是否有较大的物体.如果是,他将会关闭屏幕