iPhone線からの距離

線からの距離を計算するiPhoneアプリ C++のサンプルコードを描いてみます。

#import “ViewController.h”

#include <memory>

#include <vector>

#include <iostream>

using namespace std;

class Vector2d {

public:

    double x;

    double y;

    Vector2d();

    Vector2d(float, float);

    Vector2d operator+(const Vector2d&) const;

    Vector2d operator-(const Vector2d&) const;

    float operator*(const Vector2d&) const;

    float operator^(const Vector2d&) const;

    static float linePointDist(Vector2d A, Vector2d B, Vector2d C);

};

Vector2d::Vector2d()

{

    x = 0.0;

    y = 0.0;

}

Vector2d::Vector2d(float sourceX, float sourceY)

{

    x = sourceX;

    y = sourceY;

}

Vector2d Vector2d::operator+(const Vector2d &v) const

{

    return Vector2d(x+v.x, y+v.y);

}

Vector2d Vector2d::operator-(const Vector2d &v) const

{

    return Vector2d(x-v.x, y-v.y);

}

// dot product

float Vector2d::operator*(const Vector2d &v) const

{

    return x * v.x + y * v.y;

}

// cross product

float Vector2d::operator^(const Vector2d &v) const

{

    return (x * v.y) – (y * v.x);

}

float Vector2d::linePointDist(Vector2d A, Vector2d B, Vector2d C){

    double dist = ((B-A)^(C-A)) / sqrt((B-A)*(B-A));

    return fabs(dist);

}

@interface ViewController ()

@end

@implementation ViewController {

    std::vector<Vector2d> _points;

}

– (void)viewDidLoad {

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor blackColor];

}

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

    CGPoint p = [[touches anyObject] locationInView:self.view];

    CALayer *mark = [CALayer layer];

    mark.frame = CGRectMake(0, 0, 40, 40);

    mark.cornerRadius = 20;

    mark.borderColor = [UIColor darkGrayColor].CGColor;

    mark.backgroundColor = [UIColor colorWithHue:0.2 saturation:0.3 brightness:1 alpha:1].CGColor;

    mark.position = p;

    [self.view.layer addSublayer:mark];

    

    _points.push_back(Vector2d(p.x, p.y));

    cout << “X:” <<  _points[0].x << ” Y:” << _points[0].y;

    if (_points.size() == 2) {

        // draw line

        UIBezierPath *path = [UIBezierPath bezierPath];

        [path moveToPoint:CGPointMake(_points[0].x, _points[0].y)];

        [path addLineToPoint:CGPointMake(_points[1].x, _points[1].y)];

        CAShapeLayer *line = [CAShapeLayer layer];

        line.path = path.CGPath;

        line.lineWidth = 2;

        line.strokeColor = [UIColor colorWithHue:0.2 saturation:0.5 brightness:1 alpha:1].CGColor;

        [self.view.layer addSublayer:line];

        

    } else if (_points.size() == 3) {

        // calc distance

        float distance = Vector2d::linePointDist(_points[0], _points[1], _points[2]);

        UIBezierPath *p = [UIBezierPath bezierPathWithArcCenter:CGPointZero radius:distance startAngle:0 endAngle:2.0*M_PI clockwise:NO];

        CAShapeLayer *circle = [CAShapeLayer layer];

        circle.position = CGPointMake(_points[2].x, _points[2].y);

        circle.path = p.CGPath;

        circle.fillColor = [UIColor clearColor].CGColor;

        circle.lineWidth = 3;

        circle.strokeColor = [UIColor colorWithHue:0.25 saturation:0.4 brightness:1 alpha:1].CGColor;

        [self.view.layer addSublayer:circle];

        

        CABasicAnimation *scale =[CABasicAnimation animationWithKeyPath:@”transform.scale”];

        [scale setFromValue:[NSNumber numberWithFloat:0.0f]];

        [scale setToValue:[NSNumber numberWithFloat:1.0f]];

        [scale setDuration:1.0f];

        [scale setRemovedOnCompletion:NO];

        [scale setFillMode:kCAFillModeForwards];

        [circle addAnimation:scale forKey:nil];

        

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

        radius.text = [NSString stringWithFormat:@”r = %.2f”, distance];

        radius.font = [UIFont fontWithName:@”DIN Alternate” size:30];

        radius.textColor = [UIColor colorWithWhite:0.95 alpha:1];

        radius.center = CGPointMake(600, CGRectGetMidY(self.view.bounds));

        [radius sizeToFit];

        [self.view addSubview:radius];

        

        [UIView animateWithDuration:0.5 animations:^{

            radius.center = CGPointMake(CGRectGetMidX(self.view.bounds) + 60, CGRectGetMidY(self.view.bounds));

        }];

    }

}

@end