iPhone三角とベジェ

三角を使ってベジェ曲線を作成するiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SpriteKit;

@interface ViewController () <SKSceneDelegate>

@property (nonatomic, weak) SKScene *scene;

@property (nonatomic, weak) SKNode *selected;

@property (nonatomic) BOOL start;

@property (nonatomic) NSTimeInterval startTime;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    

    [self setupScene];

    [self createPoint];

    [self updateLine];

}

– (void)setupScene {

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

    SKScene *s = [[SKScene alloc] initWithSize:sv.frame.size];

    s.delegate = self;

    [sv presentScene:s];

    s.backgroundColor = [UIColor blackColor];

    [self.view addSubview:sv];

    

    self.scene = s;

}

– (void)createPoint {

    

    // red point

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

        float r = CGRectGetMaxX(self.view.bounds) * 0.35;

        float angle = -(2.0 * M_PI / 3.0) * i – M_PI * 0.8;

        SKShapeNode *p = [SKShapeNode shapeNodeWithCircleOfRadius:20];

        p.name = [NSString stringWithFormat:@”p%d”, i];

        p.fillColor = [UIColor redColor];

        p.position = CGPointMake(r * cos(angle) + CGRectGetMidX(self.view.bounds), r * sin(angle) + CGRectGetMidY(self.view.bounds));

        [self.scene addChild:p];

        

        SKLabelNode * l = [SKLabelNode labelNodeWithText:[NSString stringWithFormat:@”P%d”, i]];

        l.position = CGPointMake(20, –50);

        [p addChild:l];

    }

    

    // green point

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

        SKShapeNode *p = [SKShapeNode shapeNodeWithCircleOfRadius:10];

        p.userInteractionEnabled = NO;

        p.name = [NSString stringWithFormat:@”g%d”, i];

        p.fillColor = [UIColor greenColor];

        p.position = [self.scene childNodeWithName:[NSString stringWithFormat:@”p%d”, i]].position;

        [self.scene addChild:p];

    }

    

    // pen dot

    SKShapeNode *pen = [SKShapeNode shapeNodeWithCircleOfRadius:10];

    pen.name = @”pen”;

    pen.fillColor = [UIColor blackColor];

    pen.position = [self.scene childNodeWithName:@”p0″].position;

    [self.scene addChild:pen];

    

}

– (void)updateLine {

    SKNode *old = [self.scene childNodeWithName:@”line”];

    [old removeFromParent];

    

    CGPoint pts[] = {[self.scene childNodeWithName:@”g0″].position, [self.scene childNodeWithName:@”g1″].position};

    SKShapeNode *line = [SKShapeNode shapeNodeWithPoints:pts count:2];

    line.name = @”line”;

    line.strokeColor = [UIColor whiteColor];

    [self.scene addChild:line];

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    CGPoint p = [[touches anyObject] locationInNode:self.scene];

    SKNode *hit = [self.scene nodeAtPoint:p];

    if ([hit.name hasPrefix:@”p”]) {

        self.selected = hit;

        return;

    }

    

    self.start = YES;

    NSArray *pts = @[@”g0″, @”p1″, @”g1″, @”p2″];

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

        SKNode *pa = [self.scene childNodeWithName:pts[2 * i]];

        SKNode *pb = [self.scene childNodeWithName:pts[2 * i+1]];

        [pa runAction:[SKAction moveTo:pb.position duration:3.0]];

        self.startTime = [[NSDate date] timeIntervalSince1970];

    }

}

– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

{

    CGPoint p = [[touches anyObject] locationInNode:self.scene];

    self.selected.position = p;

}

– (void)update:(NSTimeInterval)currentTime forScene:(SKScene *)scene

{

    if (self.start) {

        CGPoint g0 = [self.scene childNodeWithName:@”g0″].position;

        CGPoint g1 = [self.scene childNodeWithName:@”g1″].position;

        SKNode *pen = [self.scene childNodeWithName:@”pen”];

        

        SKNode *dot = [SKSpriteNode spriteNodeWithColor:[UIColor redColor] size:CGSizeMake(2, 2)];

        dot.position = pen.position;

        [self.scene addChild:dot];

        

        [self updateLine];

        

        float rate = ([[NSDate date] timeIntervalSince1970] – self.startTime) / 3.0;

        if (rate <= 1.0) {

            CGVector vecg0g1 = CGVectorMake(g1.x – g0.x, g1.y – g0.y);

            

            // scale

            vecg0g1.dx *= rate;

            vecg0g1.dy *= rate;

            

            NSLog(@”rate:%f, dx:%f, dy:%f, x:%f”, rate, vecg0g1.dx, vecg0g1.dy, g0.x);

            

            pen.position = CGPointMake(g0.x + vecg0g1.dx, g0.y + vecg0g1.dy);

        }

    }

}

@end