iPhone sin球

sinカーブでくねくねしながら球を周るiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@interface ViewController () <SCNSceneRendererDelegate>

@property (nonatomic, weak) SCNView *sceneView;

@property (nonatomic) int count;

@end

struct SCoordinate {

    float r;

    float t;

    float p;

};

typedef struct SCoordinate SCoordinate;

NS_INLINE SCoordinate SCoordinateMake(float x, float y, float z) {

    SCoordinate v = {x, y, z};

    return v;

}

@interface CustomNode : SCNNode

@property (nonatomic) SCoordinate coordinate;

@property (nonatomic) float baseTheta;

@end

@implementation CustomNode

– (void)setCoordinate:(SCoordinate)coordinate {

    _coordinate = coordinate;

    float x = coordinate.r * sin(coordinate.t) * cos(coordinate.p);

    float y = coordinate.r * sin(coordinate.t) * sin(coordinate.p);

    float z = coordinate.r * cos(coordinate.t);

    self.position = SCNVector3Make(x, y, z);

}

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    [self setupScene];

    [self createSphere];

    [self createCamera];

}

– (void)setupScene {

    SCNView *sv = [[SCNView alloc] initWithFrame:self.view.bounds];

    sv.backgroundColor = [self color:0];

    sv.scene = [SCNScene scene];

    sv.autoenablesDefaultLighting = YES;

    sv.allowsCameraControl = YES;

    sv.delegate = self;

    [self.view addSubview:sv];

    

    self.sceneView = sv;

}

– (void)createSphere {

    SCNSphere *sp = [SCNSphere sphereWithRadius:20];

    sp.firstMaterial.diffuse.contents = [[self color:1] colorWithAlphaComponent:0.8];

    SCNNode *spn = [SCNNode nodeWithGeometry:sp];

    [self.sceneView.scene.rootNode addChildNode:spn];

    

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

        SCNSphere *s = [SCNSphere sphereWithRadius:1];

        s.firstMaterial.diffuse.contents = [self color:i + 1];

        s.firstMaterial.shininess = 1.0;

        CustomNode *sNode = [CustomNode node];

        sNode.baseTheta = (M_PI / 6.0) * (i+1);

        sNode.geometry = s;

        sNode.name = [NSString stringWithFormat:@”satellite”];

        sNode.coordinate = SCoordinateMake(20,sNode.baseTheta,1);

        [self.sceneView.scene.rootNode addChildNode:sNode];

    }

}

– (void)createCamera {

    SCNNode *camera = [SCNNode node];

    camera.camera = [SCNCamera camera];

    camera.position = SCNVector3Make(0, 0, 80);

    [self.sceneView.scene.rootNode addChildNode:camera];

}

– (void)renderer:(id<SCNSceneRenderer>)aRenderer updateAtTime:(NSTimeInterval)time {

    [[self.sceneView.scene.rootNode.childNodes filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@”name = %@”, @”satellite”]] enumerateObjectsUsingBlock:^(CustomNode *cn, NSUInteger idx, BOOL *stop) {

        float phi = self.count * M_PI / 50.0;

        cn.coordinate = SCoordinateMake(20, cn.baseTheta + 0.1 * sin(4 * phi), phi);

    }];

    self.count = (self.count + 1) % 100;

    

    [aRenderer setPlaying:YES];

}

#define ColorHex(rgb) [UIColor colorWithRed:((rgb & 0xFF0000) >> 16)/255.0 green:((rgb & 0xFF00) >> 8)/255.0 blue:(rgb & 0xFF) /255.0 alpha:1.0]

– (UIColor *)color:(int)i{

    if (i>4) return nil;

    int colorCode[] = {0x202A38, 0x5E606F, 0x0E606F, 0xD1DBBD, 0xF5FFCC};

    return ColorHex(colorCode[i]);

}

@end