質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1628閲覧

Swift3でタップした位置が何故か左になる

keys

総合スコア215

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/06/03 23:44

下記のgifアニメは時計の秒針です。これを、ドラックで回転させたいと思っています。不思議なことは、画面をタップしてドラッグを始めるところです。今、時計の秒針はちょうど「0時」の部分を指していますが、この部分をタップして回転させて見ると、必ずプラス90度進んだ場所でドラッグが始まってしまいます。

しかし、タップする場所を時計の秒針の9時の部分を選択すると、正確にドラッグが始まります。要は、ドラッグ開始位置が必ず時計の針で言うと「9時」の部分を指してしまいます。これを、時計の針が0時の部分からドラッグを初めても正確に回転するようにしたいです

実行動画

0時部分を選択しながらドラッグすると狂い、9時の部分を選択したままドラッグすると正確に回転する

イメージ説明

実装コード

swift

1 2import UIKit 3 4class ViewController: UIViewController { 5 6 7 let ClockBackImage = UIImageView() 8 9 override func viewDidLoad() { 10 11 // Screen Size の取得 12 let screenWidth:CGFloat = view.frame.size.width 13 let screenHeight:CGFloat = view.frame.size.height 14 15 16 //CGAffineTransform(rotationAngle: CGFloat((30.0 * M_PI) / 180.0)) 17 18 19 ClockBackImage.image = UIImage(named: "hour") 20 ClockBackImage.frame = CGRect(x:0, y:0, width:250, height:250) 21 ClockBackImage.center = CGPoint(x:screenWidth/2, y:screenHeight/2) 22 self.view.addSubview(ClockBackImage) 23 24 } 25 26 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent!) { 27 28 let touch = touches.first! 29 30 let position = touch.location(in: self.view) 31 let target = self.view.center 32 let angle = atan2(target.y-position.y, target.x-position.x) 33 ClockBackImage.transform = CGAffineTransform(rotationAngle: angle) 34 35 } 36} 37

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

原因はtouchesMovedで「現在マウスが中心からどの方向にあるか」によって直接図形の回転角度を決めているからです。そうではなく、

  • 現在の図形の回転角度をcurrentAngle
  • 最初にタッチした際の中心からの角度をangleWhenTouched
  • touchesMovedの際の中心からの角度をがangle

として、touchesMovedでcurrentAngle = currentAngle + angle - angleWhenTouchedのように図形の回転角度を更新し、それに従ってtransformを設定すれば自然な回転操作となると思います。

投稿2017/06/04 02:13

KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keys

2017/06/04 06:49

アドバイスいただきありがとうござます。今の角度に、移動前の角度 - 移動後の角度を引くというロジックは理解でき下記のURLを参考に試行を重ねているのですが、なかなかうまく行きません。お忙しい中申し訳ありませんが、もし可能であれば実装例を書いていただけませんでしょうか。「現在マウスが中心からどの方向にあるか」という部分は定数positionの部分でしょうか。これであれば、どの方向という意味がわかりかねます。よろしくお願いします
KSwordOfHaste

2017/06/04 07:05 編集

質問者さんのコードをよく見てみましょう。 let target = self.view.center let angle = atan2(target.y-position.y, target.x-position.x) targetはビューの中心ですね?atan2で求めたangleが「ビューの中心からみたpositionの方向」です。方向はX軸の正の方向を0として左回りにラジアンで求めています。
keys

2017/06/04 10:37

なるほど、、、少し理解できてきた気がします。問題の部分はatan2で求めているところなのですね。数学の知識が皆無で気がつきもしませんでした。求め方として、atan2の逆がatan、つまりatanで求めた場合の方向は3時を求めることになる。だから、0時を求めるように計算をすれば良いのですね。アドバイスいただきありがとうございます。トライしてみます
KSwordOfHaste

2017/06/04 10:55

atan2の逆関数はtanです。atanも同様の機能です。 X軸方向へdx, Y軸方向へdyだけ移動した点の元の位置からの角度を求めるのがatan2の機能です。 角度 = atan2(dy, dx); 角度 = atan(dy / dx); これらの逆関数はtanです。dy/dx = tan(角度)となります。 このあたりリファレンスには一々書いてないので高校数学の解説を参考にしてください。計算機で回転などの表現をするには必須になりますので。
keys

2017/06/05 01:17

ありがとうございます。昨晩から三角関数勉強してます。ちょうど三角関数のサインコサインタンジェントの方程式しを覚えて、三角形の比は普遍であるということを知ったぐらいで、なぜtanを使えば良いのか、またatan(swiftではatan2)やその他、三角関数と円運動の関連性がピザを連想するくらいしか理解できてませんが、少しずつわかるようになると思います
KSwordOfHaste

2017/06/05 01:42

学校でこういうのを漠然と勉強するときはイマイチ頭に入ってこないこともあるでしょうが、「プログラム組むのに必要!」となれば真剣に覚えられるものだと思います。ガンバです。
keys

2017/06/05 05:42

そうですね、今日を境に三角関数マスターしようと思います。そういえば、なんとか解決できました。tanを使った訳ではないですが、現在の座標に -90度することで、0時を起点に回転を加えることができました。ただ、普通に度数法で-90をするのではなくラジアンで - Float(M_PI) / Float(2) を引いた形で実装できました。具体的には右のような式です。KSwordOfHasteさんが想定していたのは違うものですか? let angle = atan2f(Float(target.y-position.y), Float(target.x-position.x)) - Float(M_PI) / Float(2)
KSwordOfHaste

2017/06/05 05:46

コード全体を見てみないとなんともいえないですが、操作してみて不自然な動きにならないようなら「意図通り」と言えると思いますよ~
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問