CALayerをぐるぐる回す


### 開発環境

+ XCode8.1
+ Swift3



![20161031.gif](https://qiita-image-store.s3.amazonaws.com/0/40693/c79344d1-20de-cb11-34ff-9952bce720e4.gif "20161031.gif")


相変わらずgifではちょっとわかりづらいのですが、タッチの動きに連動して回ります。
一つだけオレンジ色なのは回ってるのか見え辛かったので。（何でオレンジなのかというと、意味はないです、はい）
githubへのリンクは以下

[DaialAnimationSample](https://github.com/rnsm504/DaialAnimationSample)


#### タッチの移動分を回転角度に変換するようにする

具体的には
1. 最初のタッチの座標A(x1, y1)と円の中心座標C(xc, xy)の距離（=半径)r1を測る
2. 次のタッチの座標B(x2, y2)と円の中心座標C(cx, cy)の距離(=半径)r2を測る
3. r1とr2の比率hirituを測る
4. 座標Bにhirituを掛けてr1の円周上の座標B'を測る
5. AとB'の距離をピタゴラスの定理を利用して斜辺hとして測る
6. hにr1/(回そうとしている円の半径)r0を掛ける
7. 斜辺をr0、高さをh/2としてsinθ(=h/2 / r0)で求める。それの２倍が回転角度になる

下に図を用意しましたが、ちょっと分かり辛いです。うーむ、画像を作る技術も必要だな・・・

※黒い円が回そうとしている円
![イメージ002.jpg](https://qiita-image-store.s3.amazonaws.com/0/40693/0dd77b80-a703-180f-45e8-e17f9286d287.jpeg "イメージ002.jpg")

#### 時計回りか反対か

横方向にスワイプしたら時計回りか、逆かはy座標によります。
右向けにスワイプして、y座標が中心点より上なら時計回り、下なら逆。
縦方向にスワイプした時の向きはx座標によります。
下にスワイプして、x座標が中心点より右なら時計回り、左なら逆といった感じです。

以下に角度と向きを算出してる部分を抜き出した。

```ViewController


    //回転演出
    func rotate(_ point : CGPoint, fin : Bool) {
        //斜辺の長さを算出（半径）
        let radius = getHypotenuse(_centerPoint, point2: point)
        //最初の半径とtmpの半径の比率
        let hiritu = radius / _radius
        //最初のポイントがある円周上にpointの座標を比率で割ったものをセット
        let tmpPoint = CGPoint(x: (point.x * hiritu), y: (point.y * hiritu))
        //前回と今回のポイントの距離（斜辺）を算出して対象の円周上で作った斜辺に比率を直す
        let base = getHypotenuse(_previousPoint, point2: tmpPoint) * (_radius/_originalRadius)

        if(base != 0){
            //方向
            var clockwise = true
            
            //270〜360度
            if(_previousPoint.x > _centerPoint.x && _previousPoint.y < _centerPoint.y) {
                //
                if(point.x == _previousPoint.x) {
                    clockwise = point.y > _previousPoint.y ? true : false
                } else {
                    clockwise = point.x > _previousPoint.x ? true : false
                }
                //0〜90度
            } else if(_previousPoint.x > _centerPoint.x && _previousPoint.y > _centerPoint.y) {
                if(point.x == _previousPoint.x) {
                    clockwise = point.y > _previousPoint.y ? true : false
                } else {
                    clockwise = point.x > _previousPoint.x ? false : true
                }
                //90〜180度
            } else if(_previousPoint.x < _centerPoint.x && _previousPoint.y > _centerPoint.y) {
                if(point.x == _previousPoint.x) {
                    clockwise = point.y > _previousPoint.y ? false : true
                } else {
                    clockwise = point.x > _previousPoint.x ? false : true
                }
                //180〜270度
            } else {
                if(point.x == _previousPoint.x) {
                    clockwise = point.y > _previousPoint.y ? false : true
                } else {
                    clockwise = point.x > _previousPoint.x ? true : false
                }
            }
            //sinの計算でラジアンを算出
            let radian = (1/_originalRadius)*(base/2) * 2
            
            if(radian > 0) {
                //アニメーション
                rotateAnimeation(radian, clockwise: clockwise)
             }
        }
        
        _previousPoint = point
        _radius = getHypotenuse(_centerPoint, point2: point)
    }
    
    
    //斜辺算出
    func getHypotenuse(_ point1 : CGPoint, point2 : CGPoint) -> CGFloat {
        let  radius = CGFloat(sqrt(pow(Double(point2.x - point1.x), 2) + pow(Double(point2.y - point1.y),2)))
        
        return radius
    }
```

もっとうまく出来るのではないかと思うが、煮詰まったのでここら辺で一旦締める。
とりあえず、次はこのダイヤルに加速と減速を加えてみたい。