iPhoneアプリ ルート2長方形

正方形とその一辺を半径とする弧を使って、ルート2長方形を作図していくiPhoneアプリを作ってみます。正方形、円弧、ルート2長方形、と描いていき、最後は、ルート2長方形の2等分を繰り返していきます。


動作イメージ
XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。

サンプルコード

#import “RalliesViewController.h”

#import <QuartzCore/QuartzCore.h>

@interface RalliesViewController ()

{

    int count;

    UIView *canvas;

}

@end

@implementation RalliesViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

    self.view.backgroundColor = [self color:2];

    

    [self createGridSheet];

    [self createRegularRect];

    [self createButton];

}

– (void)createRegularRect

{

    [canvas removeFromSuperview];

    canvas = [[UIView alloc] initWithFrame:self.view.bounds];

    canvas.backgroundColor = [UIColor clearColor];

    [self.view insertSubview:canvas atIndex:0];

    

    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(50, 150, 150, 150)];

    

    CAShapeLayer *sl = [[CAShapeLayer alloc] init];

    sl.fillColor = CGColorCreateCopyWithAlpha([self color:1].CGColor, 0.5);

    sl.strokeColor = [self color:0].CGColor;

    sl.lineWidth = 2.0;

    sl.path = path.CGPath;

    

    [canvas.layer addSublayer:sl];

    [self startDraw:sl];

}

– (void)createArcWithSquareRoot

{

    UIBezierPath *path = [UIBezierPath bezierPath];

    [path moveToPoint:CGPointMake(50, 300)];

    [path addLineToPoint:CGPointMake(200, 150)];

    [path addArcWithCenter:CGPointMake(50, 300) radius:150.0 * sqrt(2) startAngle:-M_PI/4.0 endAngle:0 clockwise:YES];

    [path closePath];

    

    CAShapeLayer *sl = [[CAShapeLayer alloc] init];

    sl.fillColor = [UIColor clearColor].CGColor;

    sl.strokeColor = [self color:0].CGColor;

    sl.lineWidth = 2.0;

    sl.path = path.CGPath;

    

    [canvas.layer addSublayer:sl];

    [self startDraw:sl];

    

}

– (void)createSquareRootRectangle

{

    float w = 150 * (sqrt(2) – 1.0);

    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(200, 150, w, 150)];

    

    CAShapeLayer *sl = [[CAShapeLayer alloc] init];

    sl.fillColor = CGColorCreateCopyWithAlpha([self color:1].CGColor, 0.5);

    sl.strokeColor = [self color:0].CGColor;

    sl.lineWidth = 2.0;

    sl.path = path.CGPath;

    

    [canvas.layer addSublayer:sl];

    [self startDraw:sl];

}

– (void)createDivide

{

    // init

    [canvas removeFromSuperview];

    canvas = [[UIView alloc] initWithFrame:self.view.bounds];

    canvas.backgroundColor = [UIColor clearColor];

    [self.view insertSubview:canvas atIndex:0];

    

    float w = 150 * sqrt(2);

    

    CGRect rects[] = {

        CGRectMake(50, 150, w, 150),

        CGRectMake(50 + w/2.0, 150, w/2.0, 150),

        CGRectMake(50 + w/2.0, 150, w/2.0, 75),

        CGRectMake(50 + w/2.0, 150, w/4.0, 75),

        CGRectMake(50 + w/2.0, 150 + 75/2.0, w/4.0, 75/2.0),

    };

    

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

        UIBezierPath *path = [UIBezierPath bezierPathWithRect:rects[i]];

        CAShapeLayer *sl = [[CAShapeLayer alloc] init];

        sl.fillColor = CGColorCreateCopyWithAlpha([self color:1].CGColor, 0.3);

        sl.strokeColor = [self color:0].CGColor;

        sl.lineWidth = 2.0;

        sl.path = path.CGPath;

        sl.strokeEnd = 0.0;

        [canvas.layer addSublayer:sl];

        [self performSelector:@selector(startDraw:) withObject:sl afterDelay:0.2 * i];

    }

    

}

– (void)createButton

{

    UILabel *btn = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];

    btn.layer.cornerRadius = 50;

    btn.center = CGPointMake(160, 420);

    btn.text = @”push”;

    btn.textAlignment = NSTextAlignmentCenter;

    [self.view addSubview:btn];

    

    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(50, 50) radius:60 startAngle:0 endAngle:-M_PI/2.0 clockwise:NO];

    [path addLineToPoint:CGPointMake(50, 50)];

    [path closePath];

    CAShapeLayer *sl = [CAShapeLayer layer];

    sl.frame = btn.bounds;

    sl.fillColor = CGColorCreateCopyWithAlpha([self color:0].CGColor, 0.5);

    sl.path = path.CGPath;

    sl.anchorPoint = CGPointMake(0.5, 0.5);

    

    [btn.layer addSublayer:sl];

    

    btn.userInteractionEnabled = YES;

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(push:)];

    [btn addGestureRecognizer:tap];

}

– (void)push:(UITapGestureRecognizer*)gr

{

    count = (count + 1) % 4;

    

    CAShapeLayer *sl = [gr.view.layer.sublayers objectAtIndex:0];

    [UIView animateWithDuration:0.3 animations:^{

        sl.transform = CATransform3DRotate(sl.transform, M_PI/2.0, 0, 0, 1);

    }];

    

    switch (count) {

        case 0:

            [self createRegularRect];

            break;

            

        case 1:

            [self createArcWithSquareRoot];

            break;

            

        case 2:

            [self createSquareRootRectangle];

            break;

            

        case 3:

            [self createDivide];

            break;

            

        default:

            break;

    }

}

#pragma mark – utility methods

– (void)createGridSheet

{

    UIBezierPath *path = [UIBezierPath bezierPath];

    float size = 32;

    for (int i=0; i<320/size; i++) {

        [path moveToPoint:CGPointMake(i * size, 0)];

        [path addLineToPoint:CGPointMake(i * size, 568)];

    }

    

    for (int i=0; i<568/size; i++) {

        [path moveToPoint:CGPointMake(0, i*size)];

        [path addLineToPoint:CGPointMake(320, i*size)];

    }

    

    CAShapeLayer *sl = [[CAShapeLayer alloc] init];

    sl.strokeColor = [UIColor whiteColor].CGColor;

    sl.lineWidth = 1;

    sl.lineDashPattern = @[@8, @2];

    sl.path = path.CGPath;

    

    [self.view.layer addSublayer:sl];

}

– (void)startDraw:(CAShapeLayer*)l

{

    CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@”strokeEnd”];

    a.duration = 1.0;

    a.fromValue = @0;

    a.toValue = @1;

    [l addAnimation:a forKey:@”strokeEnd”];

    

    if (l.strokeEnd == 0) {

        l.strokeEnd = 1.0;

    }

}

#define UIColorHex(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]

– (UIColor*)color:(int)i

{

    switch (i) {

        case 0:

            return UIColorHex(0x2C4259);

        case 1:

            return UIColorHex(0x9ED9D8);

        case 2:

            return UIColorHex(0xEDE9F0);

        case 3:

            return UIColorHex(0xFAF5F7);

        case 4:

            return UIColorHex(0xD4D0D1);

        default:

            break;

    }

    return nil;

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end