iPhoneカニッツァの三角

三角がみえてくる錯視 「カニッツァの三角形」を表示するiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    CGPoint p = [[touches anyObject] locationInView:self.view];

    

    UIView *v = [[UIView alloc] initWithFrame:self.view.frame];

    v.backgroundColor = [UIColor clearColor];

    v.userInteractionEnabled = NO;

    

    [self.view addSubview:v];

    float dAngle = 2.0 * M_PI / 3.0;

    for (int i=0; i<3; i++) {

        float x = 60 * cos(dAngle * i) + p.x;

        float y = 60 * sin(dAngle * i) + p.y;

        CALayer *l = [self createCircle:20];

        l.position = CGPointMake(x, y);

        l.transform = CATransform3DMakeRotation(dAngle * i – 5.0*M_PI/6.0, 0, 0, 1);

        [v.layer addSublayer:l];

        

        CATransform3D t = CATransform3DMakeTranslation(-x + p.x, -y + p.y, 0);

        t = CATransform3DRotate(t, dAngle * i – 5.0*M_PI/6.0, 0, 0, 1);

        

        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@”transform”];

        animation.duration = 3;

        animation.fromValue = [NSValue valueWithCATransform3D:t];

        animation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(dAngle * i – 5.0*M_PI/6.0, 0, 0, 1)];

        [l addAnimation:animation forKey:nil];

    }

    

    v.layer.anchorPoint = CGPointMake(p.x/CGRectGetMaxX(v.frame), p.y/CGRectGetMaxY(v.frame));

    v.layer.position = p;

    [UIView animateWithDuration:2.0 animations:^{

        v.transform = CGAffineTransformMakeRotation(M_PI * 1.5);

    }];

}

– (CAShapeLayer *)createCircle:(float)r

{

    UIBezierPath *path = [UIBezierPath bezierPath];

    [path addArcWithCenter:CGPointZero radius:r startAngle:0 endAngle:(5.0/3.0) * M_PI clockwise:YES];

    [path addLineToPoint:CGPointZero];

    [path closePath];

    CAShapeLayer *circle = [CAShapeLayer layer];

    circle.path = path.CGPath;

    float hue = arc4random() % 10;

    circle.fillColor = [UIColor colorWithHue:hue * 0.1 saturation:0.8 brightness:1.0 alpha:0.7].CGColor;

    return circle;

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end