Skip to content

Commit

Permalink
Fix haptic feedback when wrapping around zero degrees
Browse files Browse the repository at this point in the history
  • Loading branch information
Kr0oked committed Apr 30, 2023
1 parent 7dfa266 commit 560b5c2
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 16 deletions.
14 changes: 13 additions & 1 deletion app/src/main/java/com/bobek/compass/util/MathUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ import android.hardware.SensorManager
import android.location.Location
import com.bobek.compass.model.Azimuth
import com.bobek.compass.model.DisplayRotation
import com.bobek.compass.model.DisplayRotation.*
import com.bobek.compass.model.DisplayRotation.ROTATION_0
import com.bobek.compass.model.DisplayRotation.ROTATION_180
import com.bobek.compass.model.DisplayRotation.ROTATION_270
import com.bobek.compass.model.DisplayRotation.ROTATION_90
import com.bobek.compass.model.RotationVector
import kotlin.math.roundToInt

Expand Down Expand Up @@ -76,4 +79,13 @@ object MathUtils {

fun getClosestNumberFromInterval(number: Float, interval: Float): Float =
(number / interval).roundToInt() * interval

/**
* @see <a href="https://math.stackexchange.com/questions/2275439/check-if-point-on-circle-is-between-two-other-points-on-circle">Stackexchange</a>
*/
fun isAzimuthBetweenTwoPoints(azimuth: Azimuth, pointA: Azimuth, pointB: Azimuth): Boolean {
val aToB = (pointB.degrees - pointA.degrees + 360f) % 360f
val aToAzimuth = (azimuth.degrees - pointA.degrees + 360f) % 360f
return aToB <= 180f != aToAzimuth > aToB
}
}
23 changes: 8 additions & 15 deletions app/src/main/java/com/bobek/compass/view/CompassView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -162,27 +162,20 @@ class CompassView(context: Context, attributes: AttributeSet) : ConstraintLayout
private fun handleHapticFeedback(azimuth: Azimuth) {
lastHapticFeedbackPoint
?.also { checkHapticFeedback(azimuth, it) }
?: run { initializeLastHapticFeedbackPoint(azimuth) }
?: run { updateLastHapticFeedbackPoint(azimuth) }
}

private fun checkHapticFeedback(azimuth: Azimuth, lastHapticFeedbackkPoint: Azimuth) {
val boundaryStart = lastHapticFeedbackkPoint - HAPTIC_FEEDBACK_INTERVAL
val boundaryEnd = lastHapticFeedbackkPoint + HAPTIC_FEEDBACK_INTERVAL
private fun checkHapticFeedback(azimuth: Azimuth, lastHapticFeedbackPoint: Azimuth) {
val boundaryStart = lastHapticFeedbackPoint - HAPTIC_FEEDBACK_INTERVAL
val boundaryEnd = lastHapticFeedbackPoint + HAPTIC_FEEDBACK_INTERVAL

if (azimuth < boundaryStart) {
this.lastHapticFeedbackPoint = boundaryStart
performHapticFeedback()
} else if (azimuth > boundaryEnd) {
this.lastHapticFeedbackPoint = boundaryEnd
performHapticFeedback()
if (!MathUtils.isAzimuthBetweenTwoPoints(azimuth, boundaryStart, boundaryEnd)) {
updateLastHapticFeedbackPoint(azimuth)
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
}
}

private fun performHapticFeedback() {
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
}

private fun initializeLastHapticFeedbackPoint(azimuth: Azimuth) {
private fun updateLastHapticFeedbackPoint(azimuth: Azimuth) {
val closestIntervalPoint = MathUtils.getClosestNumberFromInterval(azimuth.degrees, HAPTIC_FEEDBACK_INTERVAL)
lastHapticFeedbackPoint = Azimuth(closestIntervalPoint)
}
Expand Down
19 changes: 19 additions & 0 deletions app/src/test/java/com/bobek/compass/util/MathUtilsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@

package com.bobek.compass.util

import com.bobek.compass.model.Azimuth
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test

class MathUtilsTest {
Expand Down Expand Up @@ -60,4 +63,20 @@ class MathUtilsTest {
assertEquals(0.4f, MathUtils.getClosestNumberFromInterval(0.39f, 0.2f))
assertEquals(0.4f, MathUtils.getClosestNumberFromInterval(0.40f, 0.2f))
}

@Test
fun isAzimuthBetweenTwoPoints() {
assertTrue(MathUtils.isAzimuthBetweenTwoPoints(Azimuth(10f), Azimuth(0f), Azimuth(20f)))
assertTrue(MathUtils.isAzimuthBetweenTwoPoints(Azimuth(20f), Azimuth(10f), Azimuth(30f)))

assertFalse(MathUtils.isAzimuthBetweenTwoPoints(Azimuth(180f), Azimuth(0f), Azimuth(20f)))
assertFalse(MathUtils.isAzimuthBetweenTwoPoints(Azimuth(180f), Azimuth(10f), Azimuth(30f)))

assertTrue(MathUtils.isAzimuthBetweenTwoPoints(Azimuth(359f), Azimuth(358f), Azimuth(2f)))
assertTrue(MathUtils.isAzimuthBetweenTwoPoints(Azimuth(0f), Azimuth(358f), Azimuth(2f)))
assertTrue(MathUtils.isAzimuthBetweenTwoPoints(Azimuth(1f), Azimuth(358f), Azimuth(2f)))

assertFalse(MathUtils.isAzimuthBetweenTwoPoints(Azimuth(357f), Azimuth(358f), Azimuth(2f)))
assertFalse(MathUtils.isAzimuthBetweenTwoPoints(Azimuth(3f), Azimuth(358f), Azimuth(2f)))
}
}

0 comments on commit 560b5c2

Please sign in to comment.