sinとcosと円の関係を目で見て理解するために使って欲しいサンプル。

(XcodeのiOS6 Simulatorで試しています。)

ポイント

・点をプロットするとGraphが書けるようなViewを用意

・サンプルは画面をタッチすると、自動でグラフを描画

サンプルコード

———————–

[ Graph.h ]

———————–

@interface GraphView : UIView

– (void)plot:(CGPoint)p;

@end

———————–

[ Graph.m ]

———————–

#import “GraphView.h”

@interface GraphView()

@property (nonatomic, strong) UIBezierPath *path;

@property (nonatomic, strong) NSMutableArray *points;

@end

@implementation GraphView

@synthesize path;

@synthesize points;

– (id)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];

    if (self) {

        points = [[NSMutableArray alloc] init];

    }

    return self;

}

– (void)dealloc {

    self.path = nil;

    self.points = nil;

}

– (void)plot:(CGPoint)p

{

    [points addObject:[NSValue valueWithCGPoint:p]];

}

– (void)drawRect:(CGRect)rect

{

    if ([points count] > 1) {

        CGContextRef context = UIGraphicsGetCurrentContext();

        [[UIColor whiteColor] setStroke];

        

        CGContextSetLineWidth(context, 4);

        CGContextSetLineCap(context, kCGLineCapRound);

        CGContextSetLineJoin(context, kCGLineJoinRound);

        CGContextSetAllowsAntialiasing(context, true);

        CGPoint start = [[points objectAtIndex:0] CGPointValue];

        CGContextMoveToPoint(context, start.x, start.y);

        

        for(int i=1; i<[points count]; i++) {

            CGPoint p = [[points objectAtIndex:i] CGPointValue];

            CGContextAddLineToPoint(context, p.x, p.y);

        }

        CGContextStrokePath(context);

    }

}

@end

————————————

[ ViewController.m ]

————————————

#import “ViewController.h”

#import “GraphView.h”

#import <QuartzCore/QuartzCore.h>

@interface ViewController () {

    GraphView *sinGraph;

    GraphView *cosGraph;

    GraphView *circle;

    UIView *marker;

    CADisplayLink *timer;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

    // sin グラフ

    sinGraph = [[GraphView alloc] initWithFrame:CGRectMake(10, 10, 300, 120)];

    sinGraph.backgroundColor = [UIColor redColor];

    [self.view addSubview:sinGraph];

    // ラベル

    UILabel *sLabel = [[UILabel alloc] init];

    sLabel.text = @”sin graph”;

    [sLabel sizeToFit];

    sLabel.backgroundColor = [UIColor clearColor];

    sLabel.center = CGPointMake(70, 20);

    [self.view addSubview:sLabel];

    

    // cos グラフ

    cosGraph = [[GraphView alloc] initWithFrame:CGRectMake(10, 140, 300, 120)];

    cosGraph.backgroundColor = [UIColor blueColor];

    [self.view addSubview:cosGraph];

    // ラベル

    UILabel *cLabel = [[UILabel alloc] init];

    cLabel.text = @”cos graph”;

    [cLabel sizeToFit];

    cLabel.backgroundColor = [UIColor clearColor];

    cLabel.center = CGPointMake(70, 150);

    [self.view addSubview:cLabel];

    

    

    //

    circle = [[GraphView alloc] initWithFrame:CGRectMake(10, 270, 300, 190)];

    circle.backgroundColor = [UIColor orangeColor];

    [self.view addSubview:circle];

    

    // 円の上を回るマーカー

    marker = [[UIView alloc] initWithFrame:CGRectMake(-10, –10, 10, 10)];

    marker.backgroundColor = [UIColor blackColor];

    marker.layer.cornerRadius = 5.0;

    [self.view addSubview:marker];

}

– (void)start

{

    timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(tick:)];

    [timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

}

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

{

    [self start];

}

– (void)tick:(CADisplayLink*)sender

{

    static float x;

    static float w;

    // sin

    CGPoint sinPoint = CGPointMake(x, 20 * sin(w) + 60);

    [sinGraph plot:sinPoint];

        

    // cos

    CGPoint cosPoint = CGPointMake(x, 20 * cos(w) + 60);

    [cosGraph plot:cosPoint];

    

    // circle

    CGPoint circlePoint = CGPointMake(-80 * cos(w) + 150, 80 * sin(w) + 90);

    [circle plot:circlePoint];

    marker.center = [circle convertPoint:circlePoint toView:self.view];

    

    

    [sinGraph setNeedsDisplay];

    [cosGraph setNeedsDisplay];

    [circle setNeedsDisplay];

    

    // next

    x += 0.2;

    w += M_PI * 0.005;

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end