Search code examples
iosswifttouchesmoved

Is this the correct way to make an if statement for my rotating node?


I'm able to rotate my node with one finger but I'm having trouble with my if statement. I have an if statement to add an action if I'm rotating to the left or right. I'm priniting to the console print("rotate right") when I'm rotating to the right and print("rotate left") when I'm rotating to the left. The problem I'm having is when I rotate to the right there's a spot where I rotate that prints "rotate left" and on the same spot the same thing happens when I rotate to the left it prints "rotate right". Why does that happen?

EDIT here is a picture of the spot.

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {

    for touch in touches {
        var previousAngle: CGFloat = 0.0
        let location = touch.locationInNode(self)
        let node = self.nodeAtPoint(location)

        if node.name == "circle" {
            if lastNodeSelected != nil {
                let touchedNode = lastNodeSelected!

                //lets user rotate with one finger.
                let dy = touchedNode.position.y - location.y
                let dx = touchedNode.position.x - location.x
                let angle2 = atan2(dy, dx)
                touchedNode.zRotation =  angle2

                let delta = (angle2 - previousAngle)
                if delta > 0 {
                    print("rotate left")
                }
                else {
                    print("rotate right")
                }
                previousAngle = angle2
            }
        }
    }
}

Solution

  • atan2 gives results from -π to π, so there’s a transition point where the value jumps by 2π (or -2π, depending on the direction you’re going).

    To make this work in the general case, you can’t just subtract angles; you need to figure out whether angle2 is closer to previousAngle moving clockwise or counterclockwise.

    Try:

    func rotationDelta(fromAngle a0: Double, toAngle a1: Double) -> Double {
        let π = M_PI
        return ((a1 - a0) % (2*π) + 3*π) % (2*π) - π
    }
    

    …and then:

    let delta = rotationDelta(fromAngle: previousAngle, toAngle: angle2)