開発環境
- XCode8.1
- Swift3
相変わらずgifではちょっとわかりづらいのですが、タッチの動きに連動して回ります。
一つだけオレンジ色なのは回ってるのか見え辛かったので。(何でオレンジなのかというと、意味はないです、はい)
githubへのリンクは以下
タッチの移動分を回転角度に変換するようにする
具体的には
- 最初のタッチの座標A(x1, y1)と円の中心座標C(xc, xy)の距離(=半径)r1を測る
- 次のタッチの座標B(x2, y2)と円の中心座標C(cx, cy)の距離(=半径)r2を測る
- r1とr2の比率hirituを測る
- 座標Bにhirituを掛けてr1の円周上の座標B'を測る
- AとB'の距離をピタゴラスの定理を利用して斜辺hとして測る
- hにr1/(回そうとしている円の半径)r0を掛ける
- 斜辺をr0、高さをh/2としてsinθ(=h/2 / r0)で求める。それの2倍が回転角度になる
下に図を用意しましたが、ちょっと分かり辛いです。うーむ、画像を作る技術も必要だな・・・
時計回りか反対か
横方向にスワイプしたら時計回りか、逆かはy座標によります。
右向けにスワイプして、y座標が中心点より上なら時計回り、下なら逆。
縦方向にスワイプした時の向きはx座標によります。
下にスワイプして、x座標が中心点より右なら時計回り、左なら逆といった感じです。
以下に角度と向きを算出してる部分を抜き出した。
//回転演出
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
}
もっとうまく出来るのではないかと思うが、煮詰まったのでここら辺で一旦締める。
とりあえず、次はこのダイヤルに加速と減速を加えてみたい。