围绕中心旋转矩形

10
我正在使用Brad Larsen的改编版轨迹球应用程序进行游戏。
我有两个视图,相互之间呈60度角,想知道如何使旋转位于(非封闭)矩形的中心?

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

enter image description here enter image description here enter image description here

代码(修改为只绕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的代码 - 尝试了各种更改锚点的测试,但没有成功。 - ESoft
将锚点设置为中心,然后旋转。 - Abdullah Umer
图片上看不到任何旋转。您是否设置了子层变换的m45参数? - Bernd Rabe
旋转是围绕x轴进行的,因此在图像#2中可以看到。 - ESoft
3个回答

2
你需要将每个三角形边的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];
}

1

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

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

0

你应该将imageView的superView设置为透视显示:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接