iPhone最適な辺を選択

三角形の周の長さが一番長くなるような線を3つ選ぶiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

#include <memory>

#include <vector>

#include <algorithm>

using namespace std;

class EdgesSolver {

public:

    float a, b, c;

    void solveBestThree(vector<float>);

};

void EdgesSolver::solveBestThree(vector<float> edges) {

    sort(edges.begin(), edges.end());

    for (auto i = edges.size() – 3; i > 0; i++) {

        if (edges[i+2] < edges[i+1] + edges[i]) {

            a = edges[i]; // small

            b = edges[i+1];

            c = edges[i+2]; // max

            return;

        }

    }

}

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    

    self.view.backgroundColor = [UIColor colorWithWhite:0.4 alpha:1];

    

    [self createEdges];

}

– (void)createEdges {

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

        CALayer *edge = [CALayer layer];

        edge.name = @”edge”;

        float l = (arc4random() % 2500) * 0.1 + 10;

        edge.frame = CGRectMake(0, 0, l, 2);

        edge.backgroundColor = [UIColor colorWithHue:i * 0.01 saturation:0.2 brightness:1 alpha:1].CGColor;

        edge.position = CGPointMake(CGRectGetMidX(self.view.bounds), 7 * i + 100);

        [self.view.layer addSublayer:edge];

    }

}

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

{

    vector<float> edges;

    for (CALayer *l in self.view.layer.sublayers) {

        edges.push_back(l.frame.size.width);

    }

    

    shared_ptr<EdgesSolver> cppClass(new EdgesSolver());

    cppClass->solveBestThree(edges);

    

    CALayer *maxL, *midL, *minL;

    for (CALayer *l in self.view.layer.sublayers) {

        if (l.frame.size.width == cppClass->a) {

            minL = l;

        } else if (l.frame.size.width == cppClass->b) {

            midL = l;

        } else if (l.frame.size.width == cppClass->c) {

            l.position = CGPointMake(l.position.x, 240);

            maxL = l;

        }

    }

    

    float a = minL.frame.size.width;

    float b = midL.frame.size.width;

    float c = maxL.frame.size.width;

    

    float cosB = (c*c + a*a – b*b) / (2.0 * a * c);

    minL.position = CGPointMake(CGRectGetMaxX(maxL.frame) – a * cosB * 0.5, maxL.position.y – a * sqrt(1 – cosB*cosB) * 0.5);

    minL.transform = CATransform3DMakeRotation(acos(cosB), 0, 0, 1);

    float cosA = (c*c + b*b – a*a) / (2.0 * c * b);

    midL.position = CGPointMake(maxL.frame.origin.x + b * cosA * 0.5, maxL.position.y – b * sqrt(1 – cosA*cosA) * 0.5);

    midL.transform = CATransform3DMakeRotation(-acos(cosA), 0, 0, 1);

    }

– (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

}

@end