2010-06-15 3 views
1

J'ai un code existant pour le suivi des positions multi-touch, puis le déplacement, la rotation et la mise à l'échelle de l'élément - dans ce cas, une image - de manière appropriée.iPhone multi-touch déplacer, mettre à l'échelle et faire pivoter, comment éviter l'échelle?

Le code fonctionne très bien et en soi est parfait, cependant pour cette tâche particulière, j'ai besoin du mouvement et de la rotation SEULEMENT. J'ai passé du temps à essayer de comprendre ce qui se passe dans cette routine, mais les maths ne sont pas mon point fort alors je voulais voir si quelqu'un pouvait aider?

- (CGAffineTransform)incrementalTransformWithTouches:(NSSet *)touches 
{ 
    NSArray *sortedTouches = [[touches allObjects] sortedArrayUsingSelector:@selector(compareAddress:)]; 
    NSInteger numTouches = [sortedTouches count]; 

// No touches 
if (numTouches == 0) { 
     return CGAffineTransformIdentity; 
    } 

// Single touch 
if (numTouches == 1) { 
     UITouch *touch = [sortedTouches objectAtIndex:0]; 
     CGPoint beginPoint = *(CGPoint *)CFDictionaryGetValue(touchBeginPoints, touch); 
     CGPoint currentPoint = [touch locationInView:self.superview]; 
    return CGAffineTransformMakeTranslation(currentPoint.x - beginPoint.x, currentPoint.y - beginPoint.y); 
} 

// If two or more touches, go with the first two (sorted by address) 
UITouch *touch1 = [sortedTouches objectAtIndex:0]; 
UITouch *touch2 = [sortedTouches objectAtIndex:1]; 

    CGPoint beginPoint1 = *(CGPoint *)CFDictionaryGetValue(touchBeginPoints, touch1); 
    CGPoint currentPoint1 = [touch1 locationInView:self.superview]; 
    CGPoint beginPoint2 = *(CGPoint *)CFDictionaryGetValue(touchBeginPoints, touch2); 
    CGPoint currentPoint2 = [touch2 locationInView:self.superview]; 

double layerX = self.center.x; 
double layerY = self.center.y; 

double x1 = beginPoint1.x - layerX; 
double y1 = beginPoint1.y - layerY; 
double x2 = beginPoint2.x - layerX; 
double y2 = beginPoint2.y - layerY; 
double x3 = currentPoint1.x - layerX; 
double y3 = currentPoint1.y - layerY; 
double x4 = currentPoint2.x - layerX; 
double y4 = currentPoint2.y - layerY; 

// Solve the system: 
// [a b t1, -b a t2, 0 0 1] * [x1, y1, 1] = [x3, y3, 1] 
// [a b t1, -b a t2, 0 0 1] * [x2, y2, 1] = [x4, y4, 1] 

double D = (y1-y2)*(y1-y2) + (x1-x2)*(x1-x2); 
if (D < 0.1) { 
     return CGAffineTransformMakeTranslation(x3-x1, y3-y1); 
    } 

double a = (y1-y2)*(y3-y4) + (x1-x2)*(x3-x4); 
double b = (y1-y2)*(x3-x4) - (x1-x2)*(y3-y4); 
double tx = (y1*x2 - x1*y2)*(y4-y3) - (x1*x2 + y1*y2)*(x3+x4) + x3*(y2*y2 + x2*x2) + x4*(y1*y1 + x1*x1); 
double ty = (x1*x2 + y1*y2)*(-y4-y3) + (y1*x2 - x1*y2)*(x3-x4) + y3*(y2*y2 + x2*x2) + y4*(y1*y1 + x1*x1); 

return CGAffineTransformMake(a/D, -b/D, b/D, a/D, tx/D, ty/D); 
} 

J'ai essayé de lire le travail de la matrice, mais je ne peux pas le comprendre entièrement. Plus susceptible d'être le problème est les calculs, qui, comme je le mentionne n'est pas mon point fort. Ce dont j'ai besoin de cette routine est une transformation qui effectue mon mouvement et la rotation mais ignore l'échelle - donc la distance entre les 2 points tactiles est ignorée et l'échelle n'est pas affectée. J'ai regardé d'autres routines sur Internet pour gérer la rotation multi-touch, mais toutes celles que j'ai essayées avaient des problèmes d'une manière ou d'une autre (douceur, saut lors du levage des doigts, etc.), alors que le code ci-dessus est bon pour déplacer, mettre à l'échelle et faire pivoter les actions.

Toute aide appréciée!

Répondre

0

quelque chose comme ça:

CGAffineTransform transform = self.view.transform; 
float scale = sqrt(transform.a*transform.a + transform.c*transform.c); 
self.view.transform = CGAffineTransformScale(transform, 1/scale, 1/scale); 

A la fin de votre touchesMoved: withEvent: et les méthodes updateOriginalTransformForTouches. Fondamentalement, vous calculez la valeur d'échelle actuelle, puis multipliez votre matrice de transformation par la valeur d'échelle inversée.

Questions connexes