From 03cbde826f59bf1a9617e103ee1426869f07db09 Mon Sep 17 00:00:00 2001 From: Jacob Christie Date: Tue, 5 Mar 2019 19:03:33 -0400 Subject: [PATCH 1/3] Updated `PieRadarChartViewBase.sampleVelocity(touchLocation:)` algorithm. --- .../Charts/Charts/PieRadarChartViewBase.swift | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/Source/Charts/Charts/PieRadarChartViewBase.swift b/Source/Charts/Charts/PieRadarChartViewBase.swift index 0821603968..5fb34caa00 100755 --- a/Source/Charts/Charts/PieRadarChartViewBase.swift +++ b/Source/Charts/Charts/PieRadarChartViewBase.swift @@ -668,27 +668,21 @@ open class PieRadarChartViewBase: ChartViewBase private func sampleVelocity(touchLocation: CGPoint) { - let currentTime = CACurrentMediaTime() - - _velocitySamples.append(AngularVelocitySample(time: currentTime, angle: angleForPoint(x: touchLocation.x, y: touchLocation.y))) - + let currentSample: AngularVelocitySample = { + let time = CACurrentMediaTime() + let angle = angleForPoint(x: touchLocation.x, y: touchLocation.y) + return AngularVelocitySample(time: time, angle: angle) + }() + // Remove samples older than our sample time - 1 seconds - var i = 0, count = _velocitySamples.count - while (i < count - 2) - { - if currentTime - _velocitySamples[i].time > 1.0 - { - _velocitySamples.remove(at: 0) - i -= 1 - count -= 1 - } - else - { - break - } - - i += 1 - } + // while keeping at least one samples + let index = _velocitySamples + .dropLast() + .lastIndex { $0.time < currentSample.time - 1 } + if let index = index { + _velocitySamples.remove(at: index) + } + _velocitySamples.append(currentSample) } private func calculateVelocity() -> CGFloat From f5a3a21d2e4b5a68871e6d77261dc740974fe67d Mon Sep 17 00:00:00 2001 From: Jacob Christie Date: Tue, 5 Mar 2019 19:14:47 -0400 Subject: [PATCH 2/3] Updated `PieRadarChartViewBase.calculateVelocity` algorithm --- .../Charts/Charts/PieRadarChartViewBase.swift | 59 +++++++------------ 1 file changed, 20 insertions(+), 39 deletions(-) diff --git a/Source/Charts/Charts/PieRadarChartViewBase.swift b/Source/Charts/Charts/PieRadarChartViewBase.swift index 5fb34caa00..829428d6ac 100755 --- a/Source/Charts/Charts/PieRadarChartViewBase.swift +++ b/Source/Charts/Charts/PieRadarChartViewBase.swift @@ -687,40 +687,28 @@ open class PieRadarChartViewBase: ChartViewBase private func calculateVelocity() -> CGFloat { - if _velocitySamples.isEmpty - { - return 0.0 - } - - var firstSample = _velocitySamples[0] - var lastSample = _velocitySamples[_velocitySamples.count - 1] - + guard var firstSample = _velocitySamples.first, + var lastSample = _velocitySamples.last + else { return 0 } + // Look for a sample that's closest to the latest sample, but not the same, so we can deduce the direction - var beforeLastSample = firstSample - for i in stride(from: (_velocitySamples.count - 1), through: 0, by: -1) - { - beforeLastSample = _velocitySamples[i] - if beforeLastSample.angle != lastSample.angle - { - break - } - } - + let beforeLastSample = _velocitySamples.last { $0.angle != lastSample.angle } + ?? firstSample + // Calculate the sampling time - var timeDelta = lastSample.time - firstSample.time - if timeDelta == 0.0 - { - timeDelta = 0.1 - } - + let timeDelta: CGFloat = { + let delta = CGFloat(lastSample.time - firstSample.time) + return delta == 0 ? 0.1 : delta + }() + // Calculate clockwise/ccw by choosing two values that should be closest to each other, // so if the angles are two far from each other we know they are inverted "for sure" - var clockwise = lastSample.angle >= beforeLastSample.angle - if (abs(lastSample.angle - beforeLastSample.angle) > 270.0) - { - clockwise = !clockwise - } - + let isClockwise: Bool = { + let isClockwise = lastSample.angle >= beforeLastSample.angle + let isInverted = abs(lastSample.angle - beforeLastSample.angle) > 270.0 + return isInverted ? !isClockwise : isClockwise + }() + // Now if the "gesture" is over a too big of an angle - then we know the angles are inverted, and we need to move them closer to each other from both sides of the 360.0 wrapping point if lastSample.angle - firstSample.angle > 180.0 { @@ -732,15 +720,8 @@ open class PieRadarChartViewBase: ChartViewBase } // The velocity - var velocity = abs((lastSample.angle - firstSample.angle) / CGFloat(timeDelta)) - - // Direction? - if !clockwise - { - velocity = -velocity - } - - return velocity + let velocity = abs((lastSample.angle - firstSample.angle) / timeDelta) + return isClockwise ? velocity : -velocity } /// sets the starting angle of the rotation, this is only used by the touch listener, x and y is the touch position From 5b125b2cdaa4882781ae8c4838d8a66804859c74 Mon Sep 17 00:00:00 2001 From: Jacob Christie Date: Tue, 5 Mar 2019 19:16:02 -0400 Subject: [PATCH 3/3] Updated naming for `_velocitySamples` --- Source/Charts/Charts/PieRadarChartViewBase.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Source/Charts/Charts/PieRadarChartViewBase.swift b/Source/Charts/Charts/PieRadarChartViewBase.swift index 829428d6ac..c402c8c785 100755 --- a/Source/Charts/Charts/PieRadarChartViewBase.swift +++ b/Source/Charts/Charts/PieRadarChartViewBase.swift @@ -475,7 +475,7 @@ open class PieRadarChartViewBase: ChartViewBase var angle: CGFloat } - private var _velocitySamples = [AngularVelocitySample]() + private var velocitySamples = [AngularVelocitySample]() private var _decelerationLastTime: TimeInterval = 0.0 private var _decelerationDisplayLink: NSUIDisplayLink! @@ -663,7 +663,7 @@ open class PieRadarChartViewBase: ChartViewBase private func resetVelocity() { - _velocitySamples.removeAll(keepingCapacity: false) + velocitySamples.removeAll(keepingCapacity: false) } private func sampleVelocity(touchLocation: CGPoint) @@ -676,23 +676,23 @@ open class PieRadarChartViewBase: ChartViewBase // Remove samples older than our sample time - 1 seconds // while keeping at least one samples - let index = _velocitySamples + let index = velocitySamples .dropLast() .lastIndex { $0.time < currentSample.time - 1 } if let index = index { - _velocitySamples.remove(at: index) + velocitySamples.remove(at: index) } - _velocitySamples.append(currentSample) + velocitySamples.append(currentSample) } private func calculateVelocity() -> CGFloat { - guard var firstSample = _velocitySamples.first, - var lastSample = _velocitySamples.last + guard var firstSample = velocitySamples.first, + var lastSample = velocitySamples.last else { return 0 } // Look for a sample that's closest to the latest sample, but not the same, so we can deduce the direction - let beforeLastSample = _velocitySamples.last { $0.angle != lastSample.angle } + let beforeLastSample = velocitySamples.last { $0.angle != lastSample.angle } ?? firstSample // Calculate the sampling time