iPhoneフィボナッチ上下

フィボナッチ数は (1+√5) / 2 を使って上と下で囲める。というiPhoneアプリのサンプルコードを描いてみます。

@interface ViewController ()

@property (nonatomic, strong) NSMutableArray *fibonacciDots;

@property (nonatomic, strong) NSMutableArray *upperDots;

@property (nonatomic, strong) NSMutableArray *lowerDots;

@end

@implementation ViewController

– (void)viewDidAppear:(BOOL)animated

{

    self.view.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1];

    [self createFibonacci];

    [self createUpperLimit];

    [self createLowerLimit];

    [self createButtons];

}

– (void)createFibonacci

{

    self.fibonacciDots = [NSMutableArray array];

    

    // n = 0

    UIView *dot0 = [self createDot:CGPointMake(50, CGRectGetMaxY(self.view.bounds) – 50) color:[UIColor brownColor]];

    [self.fibonacciDots addObject:dot0];

    

    // n = 1

    UIView *dot1 = [self createDot:CGPointMake(80, CGRectGetMaxY(self.view.bounds) – 51) color:[UIColor brownColor]];

    [self.fibonacciDots addObject:dot1];

    

    // n > 1

    float fnm1 = 1;

    float fnm2 = 0;

    for (int n=2; n<13; n++) {

        float fn = fnm2 + fnm1;

        fnm2 = fnm1;

        fnm1 = fn;

        CGPoint p = CGPointMake(n * 30 + 50, CGRectGetMaxY(self.view.bounds) – fn – 50);

        UIView *dot = [self createDot:p color:[UIColor brownColor]];

        [self.fibonacciDots addObject:dot];

    }

}

– (void)createUpperLimit

{

    self.upperDots = [NSMutableArray array];

    for (int n=0; n<13; n++) {

        float val = powf((1 + sqrtf(5.0)) / 2.0 , n-1);

        CGPoint p = CGPointMake(n * 30 + 50, CGRectGetMaxY(self.view.bounds) – val – 50);

        UIView *dot = [self createDot:p color:[UIColor redColor]];

        [self.upperDots addObject:dot];

    }

}

– (void)createLowerLimit

{

    self.lowerDots = [NSMutableArray array];

    for (int n=0; n<13; n++) {

        float val = powf((1 + sqrtf(5.0)) / 2.0 , n-2);

        CGPoint p = CGPointMake(n * 30 + 50, CGRectGetMaxY(self.view.bounds) – val – 50);

        UIView *dot = [self createDot:p color:[UIColor blueColor]];

        [self.lowerDots addObject:dot];

    }

}

– (UIView *)createDot:(CGPoint)p color:(UIColor *)color

{

    UIView *dot = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 5)];

    dot.alpha = 0;

    dot.backgroundColor = [color colorWithAlphaComponent:0.7];

    dot.center = p;

    dot.transform = CGAffineTransformMakeRotation(M_PI/4.0);

    [self.view addSubview:dot];

    

    return dot;

}

– (void)createButtons

{

    NSArray *titles = @[@”lower”, @”fibonacci”, @”upper”];

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

        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];

        [btn setBackgroundImage:[self colorImage:[UIColor grayColor]] forState:UIControlStateNormal];

        [btn setTitle:titles[i] forState:UIControlStateNormal];

        btn.frame = CGRectMake(100 * i + 200, 290, 80, 30);

        [self.view addSubview:btn];

        

        [btn addTarget:self action:@selector(tap:) forControlEvents:UIControlEventTouchUpInside];

    }

}

– (void)tap:(UIButton *)sender

{

    NSArray *dots;

    if ([sender.titleLabel.text isEqual:@”fibonacci”]) {

        dots = self.fibonacciDots;

    } else if ([sender.titleLabel.text isEqual:@”upper”]) {

        dots = self.upperDots;

    } else if ([sender.titleLabel.text isEqual:@”lower”]) {

        dots = self.lowerDots;

    }

    

    for (int i=0; i<dots.count; i++) {

        UIView *d = dots[i];

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * i * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            d.alpha = !d.alpha;

        });

    }

}

– (UIImage *)colorImage:(UIColor *)color

{

    CGRect rect = CGRectMake(0, 0, 1, 1);

    UIGraphicsBeginImageContext(rect.size);

    CGContextRef ctx = UIGraphicsGetCurrentContext();

    [color setFill];

    CGContextFillRect(ctx, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return image;

}

@end