【问题标题】:Rotate rectangle around center围绕中心旋转矩形
【发布时间】:2012-11-12 08:27:32
【问题描述】:

我正在使用轨迹球应用程序的Brad Larsen's adaption
我有两个彼此成 60 度角的视图,想知道如何让旋转位于这个(非闭合)矩形的中心?

在下面的图片中,我希望旋转发生在蓝线内。

代码(修改为只绕x轴旋转):

#import "MyView.h"

//=====================================================
// Defines
//=====================================================

#define DEGREES_TO_RADIANS(degrees) \
    (degrees * (M_PI / 180.0f))

//=====================================================
// Public Interface
//=====================================================

@implementation MyView

- (void)awakeFromNib
{
    transformed = [CALayer layer];
    transformed.anchorPoint = CGPointMake(0.5f, 0.5f);

    transformed.frame = self.bounds;
    [self.layer addSublayer:transformed];

    CALayer *imageLayer = [CALayer layer];
    imageLayer.frame = CGRectMake(10.0f, 4.0f, self.bounds.size.width / 2.0f, self.bounds.size.height / 2.0f);
    imageLayer.transform = CATransform3DMakeRotation(DEGREES_TO_RADIANS(60.0f), 1.0f, 0.0f, 0.0f);
    imageLayer.contents = (id)[[UIImage imageNamed:@"IMG_0051.png"] CGImage];
    imageLayer.borderColor = [UIColor yellowColor].CGColor;
    imageLayer.borderWidth = 2.0f;
    [transformed addSublayer:imageLayer];

    imageLayer = [CALayer layer];
    imageLayer.frame = CGRectMake(10.0f, 120.0f, self.bounds.size.width / 2.0f, self.bounds.size.height / 2.0f);
    imageLayer.transform = CATransform3DMakeRotation(DEGREES_TO_RADIANS(-60.0f), 1.0f, 0.0f, 0.0f);
    imageLayer.contents = (id)[[UIImage imageNamed:@"IMG_0089.png"] CGImage];
    imageLayer.borderColor = [UIColor greenColor].CGColor;
    imageLayer.borderWidth = 2.0f;

    transformed.borderColor = [UIColor whiteColor].CGColor;
    transformed.borderWidth = 2.0f;
    [transformed addSublayer:imageLayer];

    UIView *line = [[UIView alloc] initWithFrame:CGRectMake(0, self.bounds.size.height / 2.0f, self.bounds.size.width, 2)];
    [line setBackgroundColor:[UIColor redColor]];
    [self addSubview:line];

    line = [[UIView alloc] initWithFrame:CGRectMake(0, self.bounds.size.height * (1.0f / 4.0f), self.bounds.size.width, 2)];
    [line setBackgroundColor:[UIColor blueColor]];
    [self addSubview:line];

    line = [[UIView alloc] initWithFrame:CGRectMake(0, self.bounds.size.height * (3.0f / 4.0f), self.bounds.size.width, 2)];
    [line setBackgroundColor:[UIColor blueColor]];
    [self addSubview:line];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    previousLocation = [[touches anyObject] locationInView:self];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGPoint location = [[touches anyObject] locationInView:self];
    //location = CGPointMake(previousLocation.x, location.y);

    CATransform3D currentTransform = transformed.sublayerTransform;

    //CGFloat displacementInX = location.x - previousLocation.x;
    CGFloat displacementInX = previousLocation.x - location.x;
    CGFloat displacementInY = previousLocation.y - location.y;

    CGFloat totalRotation = sqrt((displacementInX * displacementInX) + (displacementInY * displacementInY));

    CGFloat angle = DEGREES_TO_RADIANS(totalRotation);
    CGFloat x = ((displacementInX / totalRotation) * currentTransform.m12 + (displacementInY/totalRotation) * currentTransform.m11);

    CATransform3D rotationalTransform = CATransform3DRotate(currentTransform, angle, x, 0, 0);

    previousLocation = location;
    transformed.sublayerTransform = rotationalTransform;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
}

- (void)dealloc {
  [super dealloc];
}

@end

【问题讨论】:

  • 我按原样使用 Brad 的代码 - 尝试了各种更改锚点的测试,但没有运气
  • 将锚点设置在中间,然后旋转。
  • 在图片上看不到任何旋转。是否设置了 sublayerTransforms m45 参数?
  • 旋转是围绕 x 轴,所以这在图像 #2 中可以看到

标签: iphone ios core-animation core-graphics


【解决方案1】:

您需要将每个三角形边的imageLayer.zPosition 设置为距三角形中心的距离(在您的情况下为等边三角形)。

如果sideHeight = self.bounds.size.height / 2.0f;
然后distanceFromCenter = ((sideHeight / 2.0f) / sqrt(3));

此外,在设置侧面旋转时,您需要将它们移动到所需的位置(在您的代码中它们是硬编码的)。

更新代码

- (void)awakeFromNib
{
    transformed = [CALayer layer];
    transformed.anchorPoint = CGPointMake(0.5f, 0.5f);

    transformed.frame = self.bounds;
    [self.layer addSublayer:transformed];

    CGFloat sideHeight = self.bounds.size.height / 2.0f;
    CGFloat distanceFromCenter = ((sideHeight / 2.0f) / sqrt(3));

    CGFloat sideC = sideHeight / 2.0f;
    CGFloat sideA = sideC / 2.0f;
    CGFloat sideB = (sqrt(3) * sideA);

    CALayer *imageLayer = [CALayer layer];
    imageLayer.frame = CGRectMake(10.0f, (self.bounds.size.height / 2.0f) - (sideHeight / 2.0f), self.bounds.size.width / 2.0f, sideHeight);
    imageLayer.transform = CATransform3DConcat(CATransform3DMakeRotation(-DEGREES_TO_RADIANS(60.0f), 1.0f, 0.0f, 0.0f),
                                               CATransform3DMakeTranslation(0, -sideA, -sideB));
    imageLayer.contents = (id)[[UIImage imageNamed:@"IMG_0051.png"] CGImage];
    imageLayer.borderColor = [UIColor yellowColor].CGColor;
    imageLayer.borderWidth = 2.0f;
    imageLayer.zPosition = distanceFromCenter;
    [transformed addSublayer:imageLayer];

    imageLayer = [CALayer layer];
    imageLayer.frame = CGRectMake(10.0f, (self.bounds.size.height / 2.0f) - (sideHeight / 2.0f), self.bounds.size.width / 2.0f, sideHeight);
    imageLayer.transform = CATransform3DConcat(CATransform3DMakeRotation(DEGREES_TO_RADIANS(60.0f), 1.0f, 0.0f, 0.0f),
                                               CATransform3DMakeTranslation(0, sideA, -sideB));
    imageLayer.contents = (id)[[UIImage imageNamed:@"IMG_0089.png"] CGImage];
    imageLayer.borderColor = [UIColor greenColor].CGColor;
    imageLayer.zPosition = distanceFromCenter;
    imageLayer.borderWidth = 2.0f;

    transformed.borderColor = [UIColor whiteColor].CGColor;
    transformed.borderWidth = 2.0f;
    [transformed addSublayer:imageLayer];

    UIView *line = [[UIView alloc] initWithFrame:CGRectMake(0, self.bounds.size.height / 2.0f, self.bounds.size.width, 2)];
    [line setBackgroundColor:[UIColor redColor]];
    [self addSubview:line];

    line = [[UIView alloc] initWithFrame:CGRectMake(0, self.bounds.size.height * (1.0f / 4.0f), self.bounds.size.width, 2)];
    [line setBackgroundColor:[UIColor blueColor]];
    [self addSubview:line];

    line = [[UIView alloc] initWithFrame:CGRectMake(0, self.bounds.size.height * (3.0f / 4.0f), self.bounds.size.width, 2)];
    [line setBackgroundColor:[UIColor blueColor]];
    [self addSubview:line];
}

【讨论】:

    【解决方案2】:

    还可以使用其他转换(我认为您需要翻译)并将它们与旋转连接起来。这个例子甚至缩放了图像,所以你得到了一个缩放、移动和旋转的图层:

    CATransform3D translate = CATransform3DMakeTranslation(yourShiftByX, yourShiftByY, 0);
    CATransform3D scale = CATransform3DMakeScale(yourRateX, yourRateY, 1);
    CATransform3D rotate = CATransform3DMakeRotation(DEGREES_TO_RADIANS(60.0f), 1.0, 0.0, 0.0);
    CATransform3D transform = CATransform3DConcat(CATransform3DConcat(rotate, scale), translate);
    // the order is important: FIRST we rotate, THEN we scale and AT LAST we position the object
    
    // now apply 'transform' to your layer
    

    【讨论】:

      【解决方案3】:

      你应该让你的 imageView superView 显示透视图:

      CATransform3D tranfrom = CATransform3DIdentity;
      tranfrom.m34 = -1.0 / z;
      imageView.superview.layer.transform = transfrom;
      

      【讨论】:

        猜你喜欢
        • 2018-08-24
        • 1970-01-01
        • 2015-03-29
        • 1970-01-01
        • 2013-08-23
        • 2013-02-14
        • 2012-10-01
        • 1970-01-01
        • 2013-12-18
        相关资源
        最近更新 更多