2012-11-12 22 views
10

Sto giocando con Brad Larsen's adaption dell'app trackball.
Ho due viste con un angolo di 60 gradi l'una rispetto all'altra e mi chiedevo come avrei ottenuto la rotazione al centro di questo rettangolo (non chiuso)?Ruota rettangolo intorno al centro

Nelle immagini seguenti avrei voluto che la rotazione si svolgesse all'interno delle linee blu.

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

Codice (modificato per solo ruotare intorno all'asse 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 
+0

Sto usando il codice di Brad come è - provato vari test con mutevoli punti di ancoraggio, ma senza fortuna – ESoft

+0

Tutto a posto :-) – ESoft

+0

impostare il punto di ancoraggio a metà e poi ruotare. –

risposta

2

È necessario impostare la imageLayer.zPosition di ciascuno dei lati del triangolo alla distanza dal centro del triangolo (che è un triangolo equilatero nel tuo caso).

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

Inoltre, quando si imposta la rotazione sui lati, è necessario spostarli nelle loro posizioni richieste (nel codice che sono fissi).

codice aggiornato

- (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

utilizzare anche altre trasformazioni (credo che avrete bisogno di traduzione) e concatenare con rotazione. Questo esempio scale anche l'immagine, in modo da ottenere una scala, spostato e lo strato ruotato:

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

si dovrebbe rendere il vostro Superview ImageView per mostrare il punto di vista:

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