今回は、「正方形の一辺 = 弧の半径」をキーワードに、iPhoneアプリのプログラミングで黄金螺旋の作図をしてみます。黄金螺旋は、黄金長方形を分割した図を使って作成していきます。ノーモン(黄金長方形を分割してできる正方形)の辺を半径として弧を描いていきます。
動作イメージ
XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。
ポイント
黄金長方形、黄金螺旋共に同じような仕組みで作図をしています。ループの内部で、黄金長方形は、正方形を描くために、UIBezierPathのaddLineToPointを、黄金螺旋はUIBezierPathのaddArcWithCenterを使用しました。図形を描く開始位置、線を描き始める角度をループの中で更新することでうまく渦を巻いていきます。
サンプルコード
#import “ViewController.h”
#import <QuartzCore/QuartzCore.h>
@interface ViewController () {
CAShapeLayer *spiral;
}
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
[self createGoldenRectangle];
[self createGoldenSpiral];
[self createButton];
}
– (void)createGoldenRectangle
{
float r = 160;
CGPoint o = CGPointMake(190, 150);
UIBezierPath *path = [UIBezierPath bezierPath];
float startAngle = M_PI;
for (int i=0; i<7; i++) {
float endAngle = startAngle – (M_PI/2.0);
[path moveToPoint:o];
[path addLineToPoint:CGPointMake(o.x + r * cos(startAngle), o.y + r * sin(startAngle))];
[path addLineToPoint:CGPointMake(o.x + r * (cos(startAngle) + cos(endAngle)), o.y + r * (sin(startAngle) + sin(endAngle)))];
[path addLineToPoint:CGPointMake(o.x + r * cos(endAngle), o.y + r * sin(endAngle))];
[path addLineToPoint:o];
float d = r * (1.0 – 1.0/1.618);
o = CGPointMake(o.x + d * cos(endAngle), o.y + d * sin(endAngle));
r = r / 1.618;
startAngle = endAngle;
}
CAShapeLayer *sl = [[CAShapeLayer alloc] init];
sl.fillColor = [UIColor clearColor].CGColor;
sl.strokeColor = [UIColor lightGrayColor].CGColor;
sl.lineWidth = 1;
sl.path = path.CGPath;
[self.view.layer addSublayer:sl];
}
– (void)createGoldenSpiral
{
float r = 160;
CGPoint o = CGPointMake(190, 150);
UIBezierPath *path = [UIBezierPath bezierPath];
float startAngle = M_PI;
for (int i=0; i<8; i++) {
float endAngle = startAngle – (M_PI/2.0);
[path addArcWithCenter:o radius:r startAngle:startAngle endAngle:endAngle clockwise:NO];
float d = r * (1.0 – 1.0/1.618);
o = CGPointMake(o.x + d * cos(endAngle), o.y + d * sin(endAngle));
r = r / 1.618;
startAngle = endAngle;
}
spiral = [[CAShapeLayer alloc] init];
spiral.fillColor = [UIColor clearColor].CGColor;
spiral.strokeColor = [UIColor blueColor].CGColor;
spiral.lineWidth = 3;
spiral.path = path.CGPath;
[self.view.layer addSublayer:spiral];
}
– (void)createButton
{
float w = 320 / 1.618;
float h = w / 1.618 / 1.618;
UILabel *btn = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, w, h)];
btn.center = CGPointMake(160, 400);
btn.text = @”Draw”;
btn.font = [UIFont fontWithName:@”Marker Felt” size:50];
btn.textColor = [UIColor whiteColor];
btn.backgroundColor = [UIColor blueColor];
btn.textAlignment = 1;
[self.view addSubview:btn];
btn.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(startDraw)];
[btn addGestureRecognizer:tap];
}
– (void)startDraw
{
CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@”strokeEnd”];
a.duration = 3.0;
a.fromValue = [NSNumber numberWithFloat:0.0f];
a.toValue = [NSNumber numberWithFloat:1.0f];
[spiral addAnimation:a forKey:@”strokeEnd”];
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end