У меня есть существующий код для отслеживания позиций мультитач и последующего перемещения, поворота и масштабирования элемента - в данном случае изображения - соответствующим образом.
Код работает очень хорошо и сам по себе идеален, однако для этой конкретной задачи мне нужно ТОЛЬКО перемещение и вращение. Я потратил время, пытаясь понять, что происходит в этой рутине, но математика не моя сильная сторона, поэтому хотел посмотреть, может ли кто-нибудь помочь?
- (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);
}
Я пытался прочитать, как работает матрица, но не могу понять полностью. Скорее всего, дело в расчетах, которые, как я уже упоминал, не моя сильная сторона.
Что мне нужно от этой процедуры, так это преобразование, которое выполняет мое движение и вращение, но игнорирует масштаб, поэтому расстояние между двумя точками касания пальца игнорируется, а масштаб не изменяется.
Я просмотрел другие процедуры в Интернете для обработки мультисенсорного вращения, но все те, которые я пробовал, так или иначе имели проблемы (плавность, прыжки при поднятии пальцев и т. Д.), Тогда как приведенный выше код подходит для перемещения, масштабирования и чередовать действия.
Любая помощь приветствуется!