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

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

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

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

Q&A

解決済

1回答

3445閲覧

swiftにおける計算結果nanについて

tamago0224

総合スコア71

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

0グッド

0クリップ

投稿2016/02/04 14:50

今回、タップすることでボールを生成し、画面下に落下するというアプリを作りました。
また、他の機能としてスライドした方向にスライド時間とスライド距離によってボールの初速を変化させるものも追加しました。
今回問題となっているのがこの機能です。
何回かスライドさせてボールを生成させてみているのですが、下記に記したプログラムの下のgetVector()関数内のdiagonal変数がときたまnanとなって値が取得できません。
同関数内の他の変数は正しく取得できているのですが、diagonal変数のみ正しい値がとれないことがあります。原因がわかる方がいらしたら解決策の方をお願いします。

swift

1import SpriteKit 2 3class ViewController: UIViewController { 4 5 var sWidth: CGFloat! 6 var sHeight: CGFloat! 7 var canvasWidth: UInt32! 8 var canvasHeight: UInt32! 9 var scene: SKScene! 10 11 var beganPos: CGPoint!//タップの開始位置座標 12 var endPos: CGPoint!//タップの終了位置座標 13 14 var startTime: NSDate! 15 16 17 override func viewDidLoad() { 18 super.viewDidLoad() 19 // Do any additional setup after loading the view, typically from a nib. 20 21 //画面の大きさを取得 22 sWidth = self.view.bounds.width 23 sHeight = self.view.bounds.height 24 25 canvasWidth = UInt32(sWidth) 26 canvasHeight = UInt32(sHeight) 27 28 //SpriteKitのviewを生成 29 let skView: SKView = SKView(frame: CGRectMake(0, 0, sWidth, sHeight)) 30 31 //シーンを生成し、設定を施す 32 scene = SKScene(size: CGSizeMake(sWidth, sHeight)) 33 scene.backgroundColor = SKColor.whiteColor() 34 skView.presentScene(scene) 35 36 37 //sceneの物理エンジンの設定 38 scene.physicsWorld.gravity = CGVectorMake(0, 0) 39 scene.physicsBody = SKPhysicsBody(edgeLoopFromRect:CGRect(x:0, y:0, width:sWidth, height:sHeight)) 40 41 self.view.addSubview(skView) 42 } 43 44 override func didReceiveMemoryWarning() { 45 super.didReceiveMemoryWarning() 46 // Dispose of any resources that can be recreated. 47 } 48 49 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 50 if let touch = touches.first { 51 let pos = touch.locationInView(self.view) 52 print("touch began position is \(pos)") 53 beganPos = pos//開始位置の取得 54 startTime = NSDate() 55 } 56 } 57 58 override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { 59 if let touch = touches.first { 60 let pos = touch.locationInView(self.view) 61 endPos = pos//終了位置の取得 62 let speed = getVector() 63 print("touch end position is \(pos)") 64 drawOval(px: pos.x, py: pos.y, speed: speed) 65 } 66 } 67 68 func drawOval(px x: CGFloat, py y: CGFloat, speed sp: CGVector) { 69 let radius:CGFloat = 20 70 let shape = SKShapeNode(circleOfRadius:radius) 71 shape.fillColor = randomColor() 72 shape.position = CGPoint(x: x, y: sHeight - y) 73 //print("shape position is \(shape.position)") 74 scene.addChild(shape) 75 76 shape.physicsBody = SKPhysicsBody(circleOfRadius: radius) 77 78 shape.physicsBody!.mass = 1.0 79 shape.physicsBody!.friction = 0.8 80 shape.physicsBody!.restitution = CGFloat(getRandomNumber(Min: 0, Max: 1.0)) 81 shape.physicsBody!.velocity = CGVectorMake(sp.dx, sp.dy) 82 } 83 84 func randomColor() -> SKColor { 85 let rand1 = CGFloat(getRandomNumber(Min: 0, Max: 1.0)) 86 let rand2 = CGFloat(getRandomNumber(Min: 0, Max: 1.0)) 87 let rand3 = CGFloat(getRandomNumber(Min: 0, Max: 1.0)) 88 let rand4 = CGFloat(getRandomNumber(Min: 0, Max: 1.0)) 89 90 let randColor = SKColor(red: rand1, green: rand2, blue: rand3, alpha: rand4) 91 92 return randColor 93 } 94 95 func getRandomNumber(Min _Min : Float, Max _Max : Float)->Float { 96 97 return ( Float(arc4random_uniform(UINT32_MAX)) / Float(UINT32_MAX) ) * (_Max - _Min) + _Min 98 } 99 100 func getDistance(began bp: CGPoint, end ep: CGPoint) -> CGFloat { 101 return sqrt((bp.x - ep.x) * (bp.x - ep.x) - (bp.y - ep.y) * (bp.y - ep.y)) 102 } 103 104 func getVector() -> CGVector { 105 let diagonal = Double(getDistance(began: beganPos, end: endPos)) 106 let base = Double(abs(endPos.x - beganPos.x)) 107 let height = Double(abs(endPos.y - beganPos.y)) 108 109 let cos: Double = Double(base / diagonal) 110 let sin: Double = Double(height / diagonal) 111 112 let time = Double(NSDate().timeIntervalSinceDate(startTime)) 113 114 let speed: Double = diagonal / time 115// print("diagonal is \(diagonal)") 116// print("time is \(time)") 117// print("speed is \(speed)") 118 119 let vector: CGVector = CGVector(dx: cos * speed, dy: sin * speed) 120 121 print("\(vector)") 122 123 return vector 124 } 125} 126

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

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

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

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

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

guest

回答1

0

ベストアンサー

getDistance()関数の引数bpとepで、x方向の移動量よりもy方向の移動量の方が大きいと、計算結果がnanになります。

投稿2016/02/04 16:02

Stripe

総合スコア2183

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

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

tamago0224

2016/02/05 08:24

に点間の距離の求め方が間違ってましたね。ご指摘ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問