Próbuję narysować obraz 2D na ekranie, który zawsze jest skierowany w górę. Jeśli użytkownik obraca telefonem, chcę mieć pewność, że mój obiekt 2D nie obraca się wraz z urządzeniem; powinien zawsze „stać pionowo”. Chcę skompensować przechylanie się użytkownika w lewo lub w prawo, ale nie przechylanie się do siebie lub do siebie.
Używam CoreMotion, aby uzyskać Pitch, Roll i Yaw z urządzenia, ale nie rozumiem, jak przełożyć punkty na kierunek w górę, zwłaszcza gdy użytkownik obraca urządzenie. Idealnie byłoby, gdybym mógł przetłumaczyć te 3 liczby na pojedynczą wartość, która zawsze powie mi, w którą stronę jest góra, bez konieczności ponownego uczenia się całej trygonometrii.
Patrzyłem na przykład czajnika 3D, ale to nie pomaga, ponieważ ten przykład jest 2D i nie potrzebuję przechylać się/przechylać w kierunku. Ponadto nie chcę używać kompasu/magnetometru, ponieważ musi on działać na iPodzie Touch.
2 odpowiedzi
Spójrz na zdjęcie, aby lepiej zrozumieć, co mówię:
Więc interesuje Cię tylko samolot XY. Akcelerometr zawsze mierzy przyspieszenie urządzenia względem swobodnego spadania. Więc kiedy trzymasz urządzenie tak, jak jest na obrazie, wartość przyspieszenia wynosi (0, -1, 0). Po przechyleniu urządzenia o 45 stopni zgodnie z ruchem wskazówek zegara wartość wynosi (0,707, -0,707, 0). Kąt można uzyskać, obliczając iloczyn skalarny aktualnej wartości przyspieszenia i pewnej osi odniesienia. Jeśli używamy wektora do góry, oś to (0,1,0). Więc iloczyn skalarny to
0*0.707 - 1*0.707 + 0*0 = -0.707
Czyli dokładnie acos(-0,707) = 45 stopni. Więc jeśli chcesz, aby obraz pozostał nieruchomy, musisz obrócić go na odwrotną stronę, tj. -45 stopni w płaszczyźnie XY. Jeśli chcesz zignorować wartość Z, bierzesz tylko osie X i Y: (X_ACCEL, Y_ACCEL, 0). Musisz zrenormalizować ten wektor (musi dać wartość 1). Następnie oblicz kąt, jak wyjaśniłem.
Apple dostarcza do tego obserwatora. Oto przykład.
Plik.h
#import <UIKit/UIKit.h>
@interface RotationAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
-(void)orientationChanged;
@end
Plik.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.
}
Podobne pytania
Powiązane pytania
Nowe pytania
objective-c
Tego znacznika należy używać tylko w przypadku pytań dotyczących funkcji Objective-C lub zależnych od kodu w języku. Tagi [cocoa] i [cocoa-touch] powinny być używane, aby zapytać o ramy lub klasy Apple. Użyj powiązanych tagów [ios], [macos], [apple-watch] i [tvos] w przypadku problemów specyficznych dla tych platform.