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

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

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

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

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Q&A

解決済

1回答

2624閲覧

電子コンパスの情報と加速度センサーの値を同時に使いたい

bacchi

総合スコア13

Xcode

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

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

0グッド

0クリップ

投稿2016/10/26 18:25

###前提・実現したいこと
iPhoneに備わっている電子コンパスと加速度センサーの二つを使用して、ある一点(動かない星と考えて、ここでは方位角:280°, 高度:70°としています)の方向に矢印が向くようにしたいと思っています。

  • 電子コンパスの情報を取得しある一点の方位角との差を算出
  • 加速度センサーの値を取得し傾きに変換して、その傾きとある一点の高度の差を算出

この二つをそれぞれ別のプロジェクトとして実機デバッグするところまではできました。
次は、それぞれの差から矢印を回転させる角度を算出してその角度の分だけ矢印を回転させようとしています。

###発生している問題・エラーメッセージ
今回困っているのは、前述の二つのプロジェクトのコードをどのような順序で記述するべきかという点です。
エラーが出ているのは、二つのクラスをまたがって使用している傾き(a)のところと、二つ目のクラスを定義しているところです。

###該当のソースコード
現時点では、二つのコードをほとんどそのまま並べただけです。

Swift3.0

1 2import UIKit 3import CoreMotion 4import CoreLocation 5 6// 加速度センサーの値を取得し、傾きに変換する 7class ViewController: UIViewController { 8 9 var myMotionManager: CMMotionManager! 10 11 override func viewDidLoad() { 12 super.viewDidLoad() 13 14 // MotionManagerを生成 15 myMotionManager = CMMotionManager() 16 17 // 更新周期を設定 18 myMotionManager.accelerometerUpdateInterval = 0.1 19 20 // 加速度の取得を開始 21 myMotionManager.startAccelerometerUpdates(to: OperationQueue.main, withHandler: {(accelerometerData, error) in 22 if let e = error { 23 print(e.localizedDescription) 24 return 25 } 26 guard let data = accelerometerData else { 27 return 28 } 29 30 // 取得した加速度を傾き(ラジアン値)に変換 31 //let ansx_radian = atan(data.acceleration.x/sqrt(pow(data.acceleration.y,2) + pow(data.acceleration.z,2))) 32 let a_radian = -atan(data.acceleration.y/sqrt(pow(data.acceleration.x,2) + pow(data.acceleration.z,2))) 33 //let ansz_radian = -atan(sqrt(pow(data.acceleration.x,2) + pow(data.acceleration.y,2))/data.acceleration.z) 34 35 // ラジアンを度に変換 36 //let ansx = ansx_radian*(180 / M_PI) 37 let a = a_radian*(180 / M_PI) // スマホの傾きをaとする 38 //let ansz = ansz_radian*(180 / M_PI) 39 40 }) 41 } 42 43 //override func didReceiveMemoryWarning() { 44 //super.didReceiveMemoryWarning() 45 // Dispose of any resources that can be recreated. 46 //} 47} 48 49// 電子コンパスの情報を取得する 50class ViewController: UIViewController, CLLocationManagerDelegate { 51 52 // UIImageViewを作成する. 53 let myImageView = UIImageView(frame: CGRect(x:0, y:0, width:300, height:300)) 54 55 var locationMgr : CLLocationManager 56 57 // 初期化処理 58 required init(coder aDecoder: NSCoder) { 59 locationMgr = CLLocationManager() 60 61 super.init(coder: aDecoder)! 62 } 63 64 override func viewDidLoad() { 65 super.viewDidLoad() 66 67 // 表示する画像を設定する. 68 let myImage = UIImage(named: "myarrow2.png") 69 70 // 画像をUIImageViewに設定する. 71 myImageView.image = myImage 72 73 // 画像を表示する座標を指定する. 74 myImageView.layer.position = CGPoint(x: self.view.bounds.width/2, y: 300.0) 75 76 // UIImageViewをViewに追加する. 77 self.view.addSubview(myImageView) 78 79 80 locationMgr.delegate = self 81 locationMgr.headingFilter = kCLHeadingFilterNone 82 locationMgr.headingOrientation = CLDeviceOrientation.portrait) 83 84 locationMgr.startUpdatingHeading() 85 } 86 87 func locationManager(manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) { 88 89 // ある一点の方位角(A:今回は280°)と現在向いている方向を比較する 90 let houi = 280 - newHeading.magneticHeading 91 92 // ある一点の高度(h:今回は70°)とスマホの傾き(a)を比較する 93 let koudo = 70 - a 94 95 // それぞれの差から矢印を回転させる角度(arrow)を算出する 96 let arrow = 90 - atan(koudo / houi) 97 98 // 回転角度の計算 99 let rt = -CGFloat(2 * M_PI * arrow / 360.0) 100 101 // 画像を回転させる 102 myImageView.transform = CGAffineTransform(rotationAngle: rt) 103 } 104 105 override func didReceiveMemoryWarning() { 106 super.didReceiveMemoryWarning() 107 // Dispose of any resources that can be recreated. 108 } 109}

###試したこと
クラスを一つにまとめてみたりしましたが、やはりよくわからないので元に戻しました。

###補足情報(言語/FW/ツール等のバージョンなど)
Swift3.0/CoreMotion、CoreLocation/Xcode8.0/iOS10.0.2/MacOS10.11

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

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

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

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

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

guest

回答1

0

ベストアンサー

aのスコープを広げればよいだけですよ。

swift

1import UIKit 2import CoreMotion 3import CoreLocation 4 5class ViewController: UIViewController, CLLocationManagerDelegate { 6 7 var myMotionManager: CMMotionManager! 8 9 // UIImageViewを作成する. 10 let myImageView = UIImageView(frame: CGRect(x:0, y:0, width:300, height:300)) 11 var locationMgr : CLLocationManager 12 var a:Double! // ★ 13 14 // 初期化処理 15 required init(coder aDecoder: NSCoder) { 16 locationMgr = CLLocationManager() 17 18 super.init(coder: aDecoder)! 19 } 20 21 override func viewDidLoad() { 22 super.viewDidLoad() 23 24 // 表示する画像を設定する. 25 let myImage = UIImage(named: "myarrow2.png") 26 27 // 画像をUIImageViewに設定する. 28 myImageView.image = myImage 29 30 // 画像を表示する座標を指定する. 31 myImageView.layer.position = CGPoint(x: self.view.bounds.width/2, y: 300.0) 32 33 // UIImageViewをViewに追加する. 34 self.view.addSubview(myImageView) 35 36 locationMgr.delegate = self 37 locationMgr.headingFilter = kCLHeadingFilterNone 38 locationMgr.headingOrientation = CLDeviceOrientation.portrait 39 40 locationMgr.startUpdatingHeading() 41 42 // MotionManagerを生成 43 myMotionManager = CMMotionManager() 44 45 // 更新周期を設定 46 myMotionManager.accelerometerUpdateInterval = 0.1 47 48 // 加速度の取得を開始 49 myMotionManager.startAccelerometerUpdates(to: OperationQueue.main, withHandler: {(accelerometerData, error) in 50 if let e = error { 51 print(e.localizedDescription) 52 return 53 } 54 guard let data = accelerometerData else { 55 return 56 } 57 58 // 取得した加速度を傾き(ラジアン値)に変換 59 //let ansx_radian = atan(data.acceleration.x/sqrt(pow(data.acceleration.y,2) + pow(data.acceleration.z,2))) 60 let a_radian = -atan(data.acceleration.y/sqrt(pow(data.acceleration.x,2) + pow(data.acceleration.z,2))) 61 //let ansz_radian = -atan(sqrt(pow(data.acceleration.x,2) + pow(data.acceleration.y,2))/data.acceleration.z) 62 63 // ラジアンを度に変換 64 //let ansx = ansx_radian*(180 / M_PI) 65 self.a = a_radian*(180 / M_PI) // スマホの傾きをaとする 66 //let ansz = ansz_radian*(180 / M_PI) 67 68 69 }) 70 71 } 72 73 func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) { 74 75 // ある一点の方位角(A:今回は280°)と現在向いている方向を比較する 76 let houi = 280 - newHeading.magneticHeading 77 78 // ある一点の高度(h:今回は70°)とスマホの傾き(a)を比較する 79 let koudo = 70 - self.a 80 81 // それぞれの差から矢印を回転させる角度(arrow)を算出する 82 let arrow = 90 - atan(koudo / houi) 83 84 // 回転角度の計算 85 let rt = -CGFloat(2 * M_PI * arrow / 360.0) 86 87 // 画像を回転させる 88 myImageView.transform = CGAffineTransform(rotationAngle: rt) 89 } 90 91 override func didReceiveMemoryWarning() { 92 super.didReceiveMemoryWarning() 93 // Dispose of any resources that can be recreated. 94 } 95} 96

投稿2016/10/27 05:22

fromageblanc

総合スコア2724

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問