
ネッカーキューブという錯視をためしてみるiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@import SceneKit;
@interface ViewController ()
@property (nonatomic, weak) SCNScene *scene;
@end
@implementation ViewController
– (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithHue:0.7 saturation:0.8 brightness:0.5 alpha:1];
[self createTitle];
[self setupScene];
[self createCamera];
[self createCube];
}
– (void)createTitle {
UILabel *title = [[UILabel alloc] init];
title.text = @”Necker Cube”;
title.font = [UIFont fontWithName:@”ChalkboardSE-Light” size:40];
title.textColor = [UIColor whiteColor];
[title sizeToFit];
title.center = CGPointMake(CGRectGetMidX(self.view.bounds), 80);
[self.view addSubview:title];
}
– (void)setupScene {
float w = CGRectGetMaxX(self.view.bounds);
SCNView *sceneView = [[SCNView alloc] initWithFrame:CGRectMake(0, 0, w, w)];
sceneView.scene = [SCNScene scene];
sceneView.backgroundColor = [UIColor colorWithHue:0.7 saturation:0.2 brightness:1 alpha:1];
sceneView.center = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds));
[self.view addSubview:sceneView];
self.scene = sceneView.scene;
}
– (void)createCamera {
SCNNode *camera = [SCNNode node];
camera.name = @”camera”;
camera.position = SCNVector3Make(0, 10, 20);
camera.camera = [SCNCamera camera];
camera.camera.usesOrthographicProjection = YES;
camera.camera.orthographicScale = 15.0;
[self.scene.rootNode addChildNode:camera];
}
– (void)createCube {
float l = 5;
SCNNode *cube = [SCNNode node];
cube.name = @”cube”;
cube.position = SCNVector3Make(0, 5.5, 0);
[self.scene.rootNode addChildNode:cube];
for (int i=0; i<12; i++) {
SCNBox *bar = [SCNBox boxWithWidth:l height:0.2 length:0.2 chamferRadius:0];
bar.firstMaterial.diffuse.contents = [UIColor grayColor];
SCNNode *barNode = [SCNNode nodeWithGeometry:bar];
[cube addChildNode:barNode];
barNode.position = SCNVector3Make(0, l/2.0, 0);
if (i < 4) {
barNode.transform = SCNMatrix4Rotate(barNode.transform, i * M_PI/2.0, 0, 0, 1);
barNode.transform = SCNMatrix4Translate(barNode.transform, 0, 0, -l/2.0);
} else if (i < 8) {
barNode.transform = SCNMatrix4Rotate(barNode.transform, i * M_PI/2.0, 0, 0, 1);
barNode.transform = SCNMatrix4Translate(barNode.transform, 0, 0, l/2.0);
} else {
barNode.transform = SCNMatrix4Rotate(barNode.transform, M_PI/2.0, 0, 1, 0);
barNode.transform = SCNMatrix4Translate(barNode.transform, l/2.0, 0, 0);
barNode.transform = SCNMatrix4Rotate(barNode.transform, i * M_PI/2.0, 0, 0, 1);
}
}
// camera
SCNNode *camera = [self.scene.rootNode childNodeWithName:@”camera” recursively:NO];
camera.constraints = @[[SCNLookAtConstraint lookAtConstraintWithTarget:cube]];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
SCNNode *cube = [self.scene.rootNode childNodeWithName:@”cube” recursively:NO];
CABasicAnimation *boxRotation =
[CABasicAnimation animationWithKeyPath:@”transform”];
boxRotation.toValue =
[NSValue valueWithSCNMatrix4:SCNMatrix4Rotate(cube.transform, M_PI,
0, 1, 0)];
boxRotation.timingFunction =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
boxRotation.repeatCount = INFINITY;
boxRotation.duration = 2.0;
[cube addAnimation:boxRotation
forKey:@”RotateTheBox”];
}
@end