diff options
Diffstat (limited to 'src/cgeo/geocaching/cgCompass.java')
| -rw-r--r-- | src/cgeo/geocaching/cgCompass.java | 157 |
1 files changed, 50 insertions, 107 deletions
diff --git a/src/cgeo/geocaching/cgCompass.java b/src/cgeo/geocaching/cgCompass.java index 4a004b3..7ecee4b 100644 --- a/src/cgeo/geocaching/cgCompass.java +++ b/src/cgeo/geocaching/cgCompass.java @@ -15,18 +15,16 @@ import android.view.View; public class cgCompass extends View { private changeThread watchdog = null; - private boolean wantStop = false; - private boolean lock = false; - private boolean drawing = false; + private volatile boolean wantStop = false; private Context context = null; private Bitmap compassUnderlay = null; private Bitmap compassRose = null; private Bitmap compassArrow = null; private Bitmap compassOverlay = null; - private Double azimuth = Double.valueOf(0); - private Double heading = Double.valueOf(0); - private Double cacheHeading = Double.valueOf(0); - private Double northHeading = Double.valueOf(0); + private double azimuth = 0.0; + private double heading = 0.0; + private double cacheHeading = 0.0; + private double northHeading = 0.0; private PaintFlagsDrawFilter setfil = null; private PaintFlagsDrawFilter remfil = null; private int compassUnderlayWidth = 0; @@ -105,11 +103,40 @@ public class cgCompass extends View { } } - protected void updateNorth(Double northHeadingIn, Double cacheHeadingIn) { + protected synchronized void updateNorth(double northHeadingIn, double cacheHeadingIn) { northHeading = northHeadingIn; cacheHeading = cacheHeadingIn; } + /** + * Compute the new value, moving by small increments. + * @param goal the goal to reach + * @param actual the actual value + * @return the new value + */ + static protected double smoothUpdate(double goal, double actual) { + double diff = goal - actual; + final boolean largeDiff = Math.abs(diff) > 5; + + double offset = 0.0; + + if (diff < 0.0) { + diff = diff + 360.0; + } else if (diff >= 360.0) { + diff = diff - 360.0; + } + + // If the difference is smaller than 1 degree, do nothing as it + // causes the arrow to vibrate. + if (diff > 1.0 && diff <= 180.0) { + offset = largeDiff ? 2.0 : 1.0; + } else if (diff > 180.0 && diff < 359.0) { + offset = largeDiff ? -2.0 : -1.0; + } + + return actual + offset; + } + private class changeThread extends Thread { @Override @@ -121,93 +148,11 @@ public class cgCompass extends View { // nothing } - if (Math.abs(azimuth - northHeading) < 2 && Math.abs(heading - cacheHeading) < 2) { - continue; - } - - lock = true; - - Double diff = Double.valueOf(0); - Double diffAbs = Double.valueOf(0); - Double tempAzimuth = Double.valueOf(0); - Double tempHeading = Double.valueOf(0); - - Double actualAzimuth = azimuth; - Double actualHeading = heading; - - diff = northHeading - actualAzimuth; - diffAbs = Math.abs(northHeading - actualAzimuth); - if (diff < 0) { - diff = diff + 360; - } else if (diff >= 360) { - diff = diff - 360; - } - - if (diff > 0 && diff <= 180) { - if (diffAbs > 5) { - tempAzimuth = actualAzimuth + 2; - } else if (diffAbs > 1) { - tempAzimuth = actualAzimuth + 1; - } else { - tempAzimuth = actualAzimuth; - } - } else if (diff > 180 && diff < 360) { - if (diffAbs > 5) { - tempAzimuth = actualAzimuth - 2; - } else if (diffAbs > 1) { - tempAzimuth = actualAzimuth - 1; - } else { - tempAzimuth = actualAzimuth; - } - } else { - tempAzimuth = actualAzimuth; + synchronized(cgCompass.this) { + azimuth = smoothUpdate(northHeading, azimuth); + heading = smoothUpdate(cacheHeading, heading); } - diff = cacheHeading - actualHeading; - diffAbs = Math.abs(cacheHeading - actualHeading); - if (diff < 0) { - diff = diff + 360; - } else if (diff >= 360) { - diff = diff - 360; - } - - if (diff > 0 && diff <= 180) { - if (diffAbs > 5) { - tempHeading = actualHeading + 2; - } else if (diffAbs > 1) { - tempHeading = actualHeading + 1; - } else { - tempHeading = actualHeading; - } - } else if (diff > 180 && diff < 360) { - if (diffAbs > 5) { - tempHeading = actualHeading - 2; - } else if (diffAbs > 1) { - tempHeading = actualHeading - 1; - } else { - tempHeading = actualHeading; - } - } else { - tempHeading = actualHeading; - } - - if (tempAzimuth >= 360) { - tempAzimuth = tempAzimuth - 360; - } else if (tempAzimuth < 0) { - tempAzimuth = tempAzimuth + 360; - } - - if (tempHeading >= 360) { - tempHeading = tempHeading - 360; - } else if (tempHeading < 0) { - tempHeading = tempHeading + 360; - } - - azimuth = tempAzimuth; - heading = tempHeading; - - lock = false; - changeHandler.sendMessage(new Message()); } } @@ -215,15 +160,16 @@ public class cgCompass extends View { @Override protected void onDraw(Canvas canvas) { - if (lock) { - return; - } - if (drawing) { - return; + double currentAzimuth; + double currentHeading; + + synchronized(this) { + currentAzimuth = azimuth; + currentHeading = heading; } - Double azimuthTemp = azimuth; - Double azimuthRelative = azimuthTemp - heading; + double azimuthTemp = currentAzimuth; + double azimuthRelative = azimuthTemp - currentHeading; if (azimuthRelative < 0) { azimuthRelative = azimuthRelative + 360; } else if (azimuthRelative >= 360) { @@ -237,7 +183,6 @@ public class cgCompass extends View { int marginLeftTemp = 0; int marginTopTemp = 0; - drawing = true; super.onDraw(canvas); canvas.save(); @@ -251,16 +196,16 @@ public class cgCompass extends View { marginLeftTemp = (getWidth() - compassRoseWidth) / 2; marginTopTemp = (getHeight() - compassRoseHeight) / 2; - canvas.rotate(-(azimuthTemp.floatValue()), canvasCenterX, canvasCenterY); + canvas.rotate((float) -azimuthTemp, canvasCenterX, canvasCenterY); canvas.drawBitmap(compassRose, marginLeftTemp, marginTopTemp, null); - canvas.rotate(azimuthTemp.floatValue(), canvasCenterX, canvasCenterY); + canvas.rotate((float) azimuthTemp, canvasCenterX, canvasCenterY); marginLeftTemp = (getWidth() - compassArrowWidth) / 2; marginTopTemp = (getHeight() - compassArrowHeight) / 2; - canvas.rotate(-(azimuthRelative.floatValue()), canvasCenterX, canvasCenterY); + canvas.rotate((float) -azimuthRelative, canvasCenterX, canvasCenterY); canvas.drawBitmap(compassArrow, marginLeftTemp, marginTopTemp, null); - canvas.rotate(azimuthRelative.floatValue(), canvasCenterX, canvasCenterY); + canvas.rotate((float) azimuthRelative, canvasCenterX, canvasCenterY); marginLeftTemp = (getWidth() - compassOverlayWidth) / 2; marginTopTemp = (getHeight() - compassOverlayHeight) / 2; @@ -269,8 +214,6 @@ public class cgCompass extends View { canvas.setDrawFilter(remfil); canvas.restore(); - - drawing = false; } @Override |
