Как обрабатывать матрицу перевода с точки зрения инвертированной оси Y
-
03-07-2019 - |
Вопрос
Мой пользовательский кейс — это приложение для iPhone, в котором я делаю анимацию масштабирования, вращения и перевода изображения.
Итак, я объединяю все и передаю в свойство Transform, но есть одна проблема:
Поскольку мои изображения различаются по размеру, их правильное расположение представляет собой проблему.Я привык к инвертированной системе координат оси Y, поэтому хочу, чтобы мое изображение располагалось ровно на расстоянии 60 пикселей по оси Y.
Итак, как мне перейти от исходной декартовой оси Y к инвертированной точке зрения оси Y?
Решение
Как указывает smacl, самый простой способ сделать это — переместить начало координат в левый нижний угол экрана, используя (screenheight - viewheight - y) вместо y в начале ваших представлений.
Однако вы можете перевернуть систему координат слоев вашего основного вида с помощью CATransform3D.Я делаю это для того, чтобы иметь возможность использовать один и тот же код макета Core Animation CALayer между моим приложением iPhone и клиентом Mac (iPhone инвертирует обычную систему координат Quartz для CALayers, чтобы она соответствовала системе координат UIViews).Все, что вам нужно сделать, чтобы включить это, — это поместить строку
self.layer.sublayerTransform = CATransform3DMakeScale(1.0f, -1.0f, 1.0f);
в коде инициализации вашего UIView, размещающего слои.Помните, что это перевернет ваши CALayers, поэтому любой рендеринг текста UIKit в этих слоях также может потребоваться перевернуть с помощью кода, подобного следующему:
CGContextSaveGState(context);
CGContextTranslateCTM(context, 0.0f, self.frame.size.height);
CGContextScaleCTM(context, 1.0f, -1.0f);
UIFont *theFont = [UIFont fontWithName:@"Helvetica" size:fontSize];
[text drawAtPoint:CGPointZero withFont:theFont];
CGContextRestoreGState(context);
Вы можете выполнить аналогичную инверсию с помощью CGAffineTransform, но для этого вам также потребуется применить перевод:
CGAffineTransform flipTransform = CGAffineTransformMakeTranslation(0.0f, self.frame.size.height);
flipTransform = CGAffineTransformScale(flipTransform, 1.0f, -1.0f);
Возможно, вы сможете использовать аффинное преобразование для преобразования исходных координат с помощью CGPointApplyAffineTransform().
Другие советы
Для каждой ординаты y = top-y, где top — это ордината Y верхней части ограничивающей рамки, в которой вы рисуете.