ルート2長方形を分割していくことで、螺旋を書くことができます。今回は、ルート2螺旋を描くiPhoneアプリを作ってみます。
動作イメージ
XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。
サンプルコード
#import “ViewController.h”
#import <QuartzCore/QuartzCore.h>
@interface ViewController ()
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [self color:0];
[self createGridSheet];
// title
UILabel *l = [[UILabel alloc] init];
l.text = @”√2 spiral”;
l.font = [UIFont systemFontOfSize:50];
[l sizeToFit];
l.backgroundColor = [UIColor clearColor];
l.textColor = [self color:2];
l.center = CGPointMake(160, 500);
[self.view addSubview:l];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self drawSquareRootOf2Rectangle];
[self drawSpiral];
}
typedef struct
{
CGPoint start;
CGPoint end;
} Line;
– (void)drawSquareRootOf2Rectangle
{
CAShapeLayer *sl = [CAShapeLayer layer];
sl.fillColor = [UIColor clearColor].CGColor;
sl.strokeColor = [self color:3].CGColor;
sl.lineWidth = 4;
[self.view.layer addSublayer:sl];
float l1 = 300;
float l2 = l1 * sqrt(2);
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(10, 50)];
[path addLineToPoint:CGPointMake(l1 + 10, 50)];
[path addLineToPoint:CGPointMake(l1 + 10, l2 + 50)];
[path addLineToPoint:CGPointMake(10, l2 + 50)];
[path closePath];
Line line[] = {
{CGPointMake(10, l2/2.0 + 50), CGPointMake(l1 + 10, l2/2.0 + 50)},
{CGPointMake(l1/2.0 + 10, l2/2.0 + 50), CGPointMake(l1/2.0 + 10, 50)},
{CGPointMake(l1/2.0 + 10, l2/4.0 + 50), CGPointMake(10, l2/4.0 + 50)},
{CGPointMake(l1/4.0 + 10, l2/4.0 + 50), CGPointMake(l1/4.0 + 10, l2/2.0 + 50)},
{CGPointMake(l1/4.0 + 10, l2 * 3.0/8.0 + 50), CGPointMake(l1/2.0 + 10, l2 * 3.0/8.0 + 50)},
};
for (int i=0; i<5; i++) {
[path moveToPoint:line[i].start];
[path addLineToPoint:line[i].end];
}
sl.path = path.CGPath;
[self startDraw:sl];
}
– (void)drawSpiral
{
float l1 = 300;
float l2 = l1 * sqrt(2);
Line line[] = {
{CGPointMake(10, l2/2.0 + 50), CGPointMake(l1 + 10, l2/2.0 + 50)},
{CGPointMake(l1/2.0 + 10, l2/2.0 + 50), CGPointMake(l1/2.0 + 10, 50)},
{CGPointMake(l1/2.0 + 10, l2/4.0 + 50), CGPointMake(10, l2/4.0 + 50)},
{CGPointMake(l1/4.0 + 10, l2/4.0 + 50), CGPointMake(l1/4.0 + 10, l2/2.0 + 50)},
{CGPointMake(l1/4.0 + 10, l2 * 3.0/8.0 + 50), CGPointMake(l1/2.0 + 10, l2 * 3.0/8.0 + 50)},
};
CAShapeLayer *sl = [CAShapeLayer layer];
sl.fillColor = [UIColor clearColor].CGColor;
sl.strokeColor = [self color:4].CGColor;
sl.lineWidth = 5;
sl.lineJoin = kCALineJoinRound;
[self.view.layer addSublayer:sl];
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(10, l2+50)];
[path addLineToPoint:line[0].end];
[path addLineToPoint:line[1].end];
[path addLineToPoint:line[2].end];
[path addLineToPoint:line[3].end];
[path addLineToPoint:line[4].end];
sl.path = path.CGPath;
[self startDraw:sl];
}
#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 = [self color:1].CGColor;
sl.lineWidth = 1;
sl.lineDashPattern = @[@5, @2];
sl.path = path.CGPath;
[self.view.layer addSublayer:sl];
}
– (void)startDraw:(CAShapeLayer*)l
{
CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@”strokeEnd”];
a.duration = 3.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(0xFEFEFE);
case 1:
return UIColorHex(0xFEFFAA);
case 2:
return UIColorHex(0xFEF475);
case 3:
return UIColorHex(0xABDCD6);
case 4:
return UIColorHex(0xFE6141);
default:
break;
}
return nil;
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end