2012-02-13 8 views
4

Je suis aux prises avec la rotation d'un triangle résultant d'un UIRotationGestureRecognizer. Si vous pouviez regarder par-dessus mon approche et offrir des suggestions, je l'apprécierais grandement.Comment faire pivoter un triangle?

Je demande à l'objet de reconnaissance de geste de la rotation, que la documentation dit est retourné en radians. Ma stratégie avait consisté à considérer chaque sommet comme un point sur un cercle qui existe entre le centre du triangle et le sommet, puis à utiliser les radians de rotation pour trouver le nouveau point sur cette circonférence. Je ne suis pas totalement sûr que ce soit une approche valable, mais je voulais au moins l'essayer. Visuellement je saurais si ça fonctionnait ou pas.

Voici le code que je crée dans cette tentative:

- (CGPoint)rotateVertex:(CGPoint)vertex byRadians:(float)radians 
{ 
    float deltaX = center.x - vertex.x; 
    float deltaY = center.y - vertex.y; 
    float currentAngle = atanf(deltaX/deltaY); 
    float newAngle = currentAngle + radians; 
    float newX = cosf(newAngle) + vertex.x; 
    float newY = sinf(newAngle) + vertex.y; 
    return CGPointMake(newX, newY); 
} 

Lorsqu'il est exécuté, il y a une légère rotation au début, mais que je continue tourner mes doigts les sommets commencent juste obtenir plus loin du point central , indiquant que je confonds quelque chose ici. J'ai regardé ce que le CGContextRotateCTM pouvait faire pour moi, mais finalement j'ai besoin de savoir ce que sont les sommets après la rotation, donc juste faire tourner le contexte graphique ne semble pas me laisser avec ces coordonnées changées. J'ai également essayé la technique décrite here mais cela a entraîné le retournement du triangle autour du second sommet, ce qui semble étrange, mais cette technique fonctionne alors avec p et q étant les coordonnées x et y du second sommet.

Merci d'avoir regardé!

Résolu: Voici la fonction corrigée. Il suppose que vous avez calculé le centre du triangle. J'ai utilisé la méthode 1/3 (x1 + x2 + x3), 1/3 (y1 + y2 + y3) décrite dans l'article Wikipedia sur Centroids. La raison pour laquelle la première liste de codes ne fonctionnait pas était que les arguments de atan2 étaient inversés. De plus, le calcul correct des valeurs delta a été inversé.

Répondre

4

Vous oubliez de multiplier par le rayon du cercle. De plus, puisque l'axe Y pointe vers le bas dans le système de coordonnées UIKit, vous devez soustraire au lieu d'ajouter les radians et annuler la coordonnée y à la fin. Et vous devez utiliser atan2 ne donne qu'une sortie dans la plage -pi/2 à pi/2:

float currentAngle = atan2f(deltaY, deltaX); 
float newAngle = currentAngle - radians; 
float radious = sqrtf(powf(deltaX, 2.0) + powf(deltaY, 2.0)); 
float newX = radius * cosf(newAngle) + vertex.x; 
float newY = -1.0 * radius * sinf(newAngle) + vertex.y; 
+0

Merci, yuji, pour le signaler. J'ai intégré cela dans le code. Cela rend une partie correcte, mais maintenant mes nouvelles coordonnées de sommets sont complètement décalées. Je mets beaucoup de messages de journalisation et retravaille les maths pour voir si les entrées peuvent être recalculées. Je n'y suis pas encore, mais je pense que tu as aidé! – tobinjim

+0

Mon plaisir. J'ai trouvé un autre problème - essayez la nouvelle version éditée ci-dessus. – yuji

+0

Vous vous déplacez plus vite que moi! Je mets des instructions de journalisation pour voir où mon erreur est faite. Je prenais conscience que Y allait dans la mauvaise direction, mais ne l'avait pas encore fait. Changez-vous le signe parce que l'axe Y sur iOS devient plus grand à la baisse, contrairement aux coordonnées cartésiennes? – tobinjim

0

La réponse est intégrée maintenant dans la question initiale. Gun timide sur le décorum approprié ;-)