トリックアート
市松模様が動いているように見える図形を書いてみる。
横長の長方形をタイル上に並べて、
その真ん中に縦長の長方形でできた円を配置する。
補足
自分で試したところ、何となく動いている気もする。
模様を目から近づけたり遠ざけたりすると、外の長方形が伸縮して見えた。
なにか、根本的なところが足りないのかも?
プログラム上のポイント
回転するイチマツ円の作り方:
長方形を配置したUIViewからUIImageを取得して、
コレを新しいUIImageViewに円上に書き込んでくるっとまわせば完成。
UIGraphicsBeginImageContextを使って実現です。
円の回転:
PanGestureRecognizerで円の中心点P0とタッチしているポイントP1を
convertPointを使って円の座標で取得 (P0はconvertPointで、P1は
locationInViewで円のUIViewを指定した)。この2点からatanで角度を計算
これを、CGAffineTransformMakeRotationに使ってクルクルする。
サンプルコード
#import “ViewController.h”
#import <QuartzCore/QuartzCore.h>
@interface ViewController () {
float dw;
float dh;
}
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
// initial size
dw = 80.0;
dh = 10.0;
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)];
[self.view addGestureRecognizer:pinch];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];
[self.view addGestureRecognizer:tap];
[self createRectBlackWhite];
}
– (void)pinch:(UIPinchGestureRecognizer*)gr
{
static float begin;
if (gr.state == UIGestureRecognizerStateBegan) {
begin = gr.scale;
}
float dif = (gr.scale – begin) / 10.0;
dw = MIN(40 * 8, MAX(dw + dif * 8, 5 * 8));
dh = MIN(40, MAX(dh + dif, 5));
for (UIView *v in self.view.subviews) {
[v removeFromSuperview];
}
[self createRectBlackWhite];
}
– (void)tap:(UITapGestureRecognizer*)gr
{
CGPoint p = [gr locationInView:self.view];
if (gr.state == UIGestureRecognizerStateEnded) {
UIImageView *v = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
v.backgroundColor = [UIColor clearColor];
UIGraphicsBeginImageContext([v.layer frame].size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, 100-p.x, 100-p.y);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
v.image = outputImage;
v.contentMode = UIViewContentModeScaleAspectFit;
v.layer.masksToBounds = YES;
v.layer.cornerRadius = 100.0;
v.backgroundColor = [UIColor blackColor];
v.center = p;
v.userInteractionEnabled = YES;
[self.view addSubview:v];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(turn:)];
[v addGestureRecognizer:pan];
}
}
– (void)turn:(UIPanGestureRecognizer*)gr
{
gr.view.transform = CGAffineTransformIdentity;
CGPoint p1 = [gr locationInView:gr.view];
CGPoint p0 = [self.view convertPoint:gr.view.center toView:gr.view];
float angle = atan2f(p1.y – p0.y, p1.x – p0.x);
gr.view.transform = CGAffineTransformMakeRotation(angle);
}
– (void)createRectBlackWhite
{
float wMax = self.view.bounds.size.width;
float hMax = self.view.bounds.size.height;
for (int w=0; w<wMax/dw; w++) {
for (int h=0; h<hMax/dh; h++) {
CGRect rect = CGRectMake(w * dw, h * dh, dw, dh);
UIView *v = [[UIView alloc] initWithFrame:rect];
if ((h+w) % 2 == 1) {
v.backgroundColor = [UIColor blackColor];
} else {
v.backgroundColor = [UIColor whiteColor];
}
[self.view addSubview:v];
}
}
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end