Почему слой моего изображения вращается вокруг края изображения, а не в центре?
Я пытаюсь повернуть изображение вокруг центра вида, используя ползунки, один для плоскостей x, y и Z. Я бы хотел, чтобы изображение вращалось внутри рамочных границ (700X700), но по какой-то причине оно вращается по краям кадра. Я попытался сбросить точку привязки, но это, похоже, ничего не делает. вот код для поворота вокруг оси Y; Вы увидите раздел узловой точки закомментирована - это не имеющий никакого влияния на всех. Есть идеи, что я делаю не так?
float angleYDeg = self.ySlider.value;
float angleYRad = (angleYDeg / 180.0) * M_PI;
// Disable Animation
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithBool:YES]
forKey:kCATransactionDisableActions];
// Get Layers
CALayer *containerLayer = [[self.imageView.layer sublayers] objectAtIndex:0];
CALayer *holder = [containerLayer valueForKey:@"__holderLayer"];
//CGPoint anchor = holder.anchorPoint;
//anchor.y = self.imageView.frame.size.height/2;
//holder.anchorPoint = anchor;
// Update xAngle Value
[containerLayer setValue:[NSNumber numberWithFloat:angleYRad] forKey:@"__angleY"];
// Apply rotations
CGFloat angleX = [[containerLayer valueForKey:@"__angleX"]floatValue];
CATransform3D holderTransform = CATransform3DMakeRotation( angleX, 1.0f, 0.0f, 0.0f);
holderTransform = CATransform3DRotate(holderTransform, angleYRad, 0.0f, 1.0f, 0.0f);
holder.transform = holderTransform;
[CATransaction commit];
// Update Label
self.yValueLabel.text = [NSString stringWithFormat:@"%4.0fº", angleYDeg];
2 ответа
Я не уверен в точном ответе на ваш вопрос, так как не могу понять, в чем дело в коде. По умолчанию все должно вращаться вокруг центра. Я написал демонстрационное приложение, которое показывает, как изменить вращение для всех осей, используя UISlider. Я разместил это на github здесь: https://github.com/perlmunger/AllAxis.git. Вот суть кода, хотя:
- (IBAction)sliderDidChange:(id)sender
{
[self setTransforms];
}
- (void)setTransforms
{
CGFloat x = [_xSlider value];
CGFloat y = [_ySlider value];
CGFloat z = [_zSlider value];
CATransform3D transform = CATransform3DIdentity;
transform.m34 = 1.0f/-800.0f; // perspective
CGFloat rotationValue = x * kRotationMaxInDegrees;
transform = CATransform3DRotate(transform,
degreesToRadians(rotationValue), 1.0f, 0.0f, 0.0f);
rotationValue = y * kRotationMaxInDegrees;
transform = CATransform3DRotate(transform,
degreesToRadians(rotationValue), 0.0f, 1.0f, 0.0f);
rotationValue = z * kRotationMaxInDegrees;
transform = CATransform3DRotate(transform,
degreesToRadians(rotationValue), 0.0f, 0.0f, 1.0f);
[[_rotationView layer] setTransform:transform];
}
Этот код создает коллективное преобразование, которое вы применяете к слою представления при каждом изменении любого слайдера.
Выполнение последовательных преобразований часто может привести к ошибкам. Когда вы преобразовываете angleX, преобразование AngleY будет выполняться на основе новой системы координат. В основном все преобразования выполняются относительно "модели" или объекта.
Большинство людей обычно ожидают, что преобразования будут сделаны относительно системы камер, или когда мы смотрим на изображение. Вполне вероятно, что желаемые результаты будут получены путем изменения порядка преобразований следующим образом:
// Apply rotations
CGFloat angleX = [[containerLayer valueForKey:@"__angleX"]floatValue];
CATransform3D holderTransform = CATransform3DMakeRotation( angleYRad, 0.0f, 1.0f, 0.0f);
holderTransform = CATransform3DRotate(holderTransform, angleX, 1.0f, 0.0f, 0.0f);
holder.transform = holderTransform;
[CATransaction commit];
Это может помочь, если вы думаете об этом как о системе жизни (хотя это не так!), Если вы рассматриваете все движения на основе координат камеры, а не координат модели.