I have made a blue ball that can be dragged by the user only on a red circled path:
I want to check how many times the user make a forward or backward lap (the start & end is at the top of the circle path), for example - If he drag the ball in a clockwise way so the laps is +1, and if he drag it to other way the laps is -1.
I tried to do this(This inculdes the dragging of the ball and my try to count laps):
@IBAction func dragBall(recognizer: UIPanGestureRecognizer) {
let point = recognizer.locationInView(self.view);
let earthX = Double(point.x)
let earthY = Double(point.y)
let midViewXDouble = Double(midViewX)
let midViewYDouble = Double(midViewY)
let angleX = (earthX - midViewXDouble)
let angleY = (earthY - midViewYDouble)
let angle = atan2(angleY, angleX)
let earthX2 = midViewXDouble + cos(angle)*100
let earthY2 = midViewYDouble + sin(angle)*100
circlePath2 = UIBezierPath(arcCenter: CGPoint(x: earthX2,y: earthY2), radius: CGFloat(10), startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true)
shapeLayer2.path = circlePath2.CGPath
if degrees == 0 {
laps += 1
print(laps)
}
}
Here is a possible solution, following the approach indicated in the comments. First you need some additional instance variables:
var previousAngle = -M_PI_2 // top position if y-coordinate points down
var totalAngle = 0.0
var laps = 0
In dragBall
, you calculate how much the angle has changed.
Since the angle can "jump" from -π to π, or vice versa, the difference
is normalised to the range -π ... π:
var delta = angle - previousAngle
if delta > M_PI {
delta -= 2 * M_PI
} else if delta < -M_PI {
delta += 2 * M_PI
}
previousAngle = angle
Then update the total change in the angle:
totalAngle += delta
and from that you can determine the number of laps:
laps = Int(floor(totalAngle/(2 * M_PI)))