我正在尝试在屏幕上绘制一个始终面向“向上”的2D图像。如果用户正在旋转手机,我想确保我的2D对象不随设备一起旋转;它应该始终“垂直”。我想补偿用户向左或向右倾斜,但不要向外倾斜或向自己倾斜。
我正在使用CoreMotion从设备中获取Pitch,Roll和Yaw,但我不明白如何将点转换为方向,特别是当用户旋转设备时。理想情况下,我可以将这3个数字转换成一个单独的值,这个值总是告诉我哪个方向上升,而不必重新学习所有三角函数。
我看过3D茶壶示例,但它无济于事,因为这个例子是2D,我不需要向外倾斜/倾斜。此外,我不想使用指南针/磁力计,因为这需要在iPod Touch上运行。
答案 0 :(得分:2)
查看图片以更好地理解我在说什么:
所以你只对XY平面感兴趣。加速度计始终测量设备相对于自由落体的加速度。因此,当您按住图像上的设备时,加速度值为(0,-1,0)。当您将设备顺时针倾斜45度时,该值为(0.707,-0.707,0)。您可以通过计算当前加速度值和某个参考轴的点积来获得角度。如果我们使用向上矢量,则轴为(0,1,0)。所以点积是
0*0.707 - 1*0.707 + 0*0 = -0.707
这恰恰是acos(-0.707)= 45度。因此,如果您希望图像保持静止,则需要在反面旋转,即在XY平面中旋转-45度。如果要忽略Z值,则只采用X和Y轴:(X_ACCEL,Y_ACCEL,0)。你需要重新规范化那个向量(它必须给出1的幅度)。然后按我的解释计算一个角度。
答案 1 :(得分:1)
File.h
#import <UIKit/UIKit.h>
@interface RotationAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
-(void)orientationChanged;
@end
File.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
//Get the device object
UIDevice *device = [UIDevice currentDevice];
//Tell it to start monitoring rthe accelermeter for orientation
[device beginGeneratingDeviceOrientationNotifications];
//Get the notification center for the app
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
//Add yourself an observer
[nc addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:device];
HeavyViewController *hvc = [[HeavyViewController alloc] init];
[[self window] setRootViewController:hvc];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
- (void)orientationChanged:(NSNotification *)note
{
NSLog(@"OrientationChanged: %d", [[note object] orientation]);
//You can use this method to change your shape.
}