2009-11-22 6 views
1

Pour sûr, c'est un truc de maths très trivial pour certains d'entre vous. Mais: Quand je tourne une vue, disons commençant à 0 degrés et tournant vers l'avant 0,1, 1, 10, 100, 150, 160, 170, 179, 179,999, et continuant à tourner dans la même direction, cela arrive , pour le dire haut et fort: BANG !!!! BAAAAAAAAANNNNNGGGG !!!! -179,9999, -170, -150, -50, 0, 50, 100, 170, 179,99, et encore: BBBBAAAANNNGGG !!! -179,999, -170, -100, et ainsi de suite ... pour sûr que vous savez ce que je veux dire ;-)Comment résoudre ce problème de rotation?

Imaginez que vous conduisez sur une route et soudainement votre miles-o-meter saute négative comme ça. Vous avez paniqué, n'est-ce pas?

Et vous savez quoi? C'est TRES mauvais pour mon algorithme. J'ai aucune idée comment résoudre ce problème autrement qu'en cochant if-else-blocks si ma valeur est soudainement inversée. Quelque chose me dit que je dois regarder certaines fonctions mathématiques comme les ondes sinus et d'autres choses. Mais mes connaissances en maths sont incroyables.

Comment puis-je résoudre ce problème? J'essaie de calculer les distances entre les angles, c'est-à-dire que j'ai deux vues où l'une réside sur l'autre, et les deux sont pivotées. Et je veux calculer la rotation globale des deux vues. Cette petite chose mais folle détruit mes calculs dès que les valeurs passent soudainement de -179,99999 à 179,99999. Aussi je ne sais pas si un 180 existe ou si les choses s'échangent quelque part à fabsf (179,999999999999999999999) si vous savez ce que je veux dire.

Par exemple: Que faudrait -170 degrés moins 50 degrés? Eh bien, je pense à -220 degrés. Mais au lieu de tourner -170 - 50 je finis par obtenir cette valeur: 40 degrés.

Comment puis-je recevoir ce que j'attends, le -220 au lieu de 40, sans aucune sorte de permutation non sécurisée? Parfois, mon auto-swapper fonctionne, mais parfois ce n'est pas dû à des incprécisions de maths.

Édition: Je calcule les angles à partir de la propriété transform.rotation.z des couches de la vue.

+0

Vous devriez être un peu plus clair sur l'origine de vos angles. Quelle partie de votre programme les calcule? –

+0

ajouté Edit: Je calcule les angles de la propriété transform.rotation.z des couches de la vue –

Répondre

5

La vue n'est pas une représentation canonique de vos données, l'interrogation vous informe sur l'état visuel du système, rien de plus. Si vous vous souciez d'une représentation particulière de l'angle, vous ne devriez pas le lire depuis transform, vous devriez le stocker dans votre modèle ou votre contrôleur selon vos besoins, et régler l'état de votre vue en fonction de cela.

@interface MyViewController: UIViewController { 
    CGFloat rotation; 
} 

@property (nonatomic) CGFloat rotation; 

@end 

@implementation MyViewController 
@synthesize rotation; 

- (void)setRotation:(CGFloat)rotation_ { 
    rotation = rotation_; 
    // Do whatever math you want and set the transform of the view based on that; 
} 
@end 
+0

Cher monsieur, je veux calculer le taux de changement d'angle de l'iPhone le long de l'axe des y, Pouvez-vous s'il vous plaît me fournir une manière précise de le faire? Puis-je utiliser une matrice de rotation pour y arriver? Désolé de poser cette question dans cette question, mais je suis désespéré pour une réponse. Merci d'avance! – sam

1

Ce que vous voyez ici est que l'angle mathématique est modulaire comme une horloge. Sur une horloge 11 + 2 == 1 pas 13. De même, vous pouvez représenter tous les angles comme des rotations négatives ou positives. Donc, +180 == (- 180). Donc, 179 + 2 = (- 179). La transformation calcule la rotation distante la plus courte à partir de la rotation zéro d'origine. Évidemment, la rotation la plus courte de 181 degrés est en fait une rotation négative de -179 degrés.

Les transformations ne sont pas cumulatives à moins que vous n'alimentiez la même transformation dans le calcul de transformation. Cela signifie que si vous créez une transformation pour faire pivoter une vue de 45 degrés et que vous l'appliquez ensuite deux fois, vous obtenez seulement 45 degrés de rotation. Pour obtenir une rotation cumulative, vous devez utiliser une fonction comme CGAffineTransformRotate et continuer à lui donner la transformation de la rotation précédente.

Cela produira une rotation en douceur dans le même sens aussi longtemps que vous le nourrissez angles < 180.

1

Pour votre CALayer de UIView, la transformation de la propriété est un struct CATransform3D.Il n'y a pas de membre de rotation de cette structure, mais Apple a fourni un keypath de commodité pour définir et lire la rotation à partir de cette structure. Le passage du positif au négatif est un artefact des calculs utilisés pour déterminer la rotation de la structure. Ce calcul est décrit pour l'équivalent 2D de CATransform3D, CGAffineTransform, dans la section "The Math Behind the Matrices" du Guide de programmation 2D de Quartz.

Pour en tenir compte, vous pouvez faire les calculs vous-même code à l'aide que je fournis dans this answer:

CATransform3D rotationTransform = [(CALayer *)[self.layer presentationLayer] transform]; 
float angle; 
if (rotationTransform.m11 < 0.0f) 
     angle = 180.0f - (asin(rotationTransform.m12) * 180.0f/M_PI); 
else 
     angle = asin(rotationTransform.m12) * 180.0f/M_PI; 

Cela devrait donner des valeurs d'angle allant de 0 à 360. Ceci inversera sur une fois que vous traversez 0 ou 360, en raison de la nature cyclique de la rotation.

+0

Cher monsieur, je veux calculer le taux de changement d'angle de l'iphone le long de l'axe des y, Pouvez-vous s'il vous plaît me fournir un moyen précis de le faire? Puis-je utiliser une matrice de rotation pour y arriver? Désolé de poser cette question dans cette question, mais je suis désespéré pour une réponse. Merci d'avance! – sam