2

I have a custom map (canvas) that I am drawing a map pointer on. I am updating it in my onLocationChanged method of my main class, however I am struggling to get the bitmap to rotate. getBearing() doesn't seem to work (at least not for me) and so I am working to find the slope between points on the map. Any help would be greatly appreciated.

public void setBearing(Point prev, Point curr){

  float slope = 1;
  if (prev.x - curr.x !=0){
     slope = (float) ((y1-y2)/(x1-x2));
     bearing = (float) Math.atan(slope);
  }

}

...

Paint p = new Paint();
Matrix matrix = new Matrix();
matrix.postRotate(bearing, coords.x, coords.y);
Bitmap rotatedImage = Bitmap.createBitmap(image, 0, 0, image.getWidth(), 
                                          image.getHeight(), matrix, true);
canvas.drawBitmap(rotatedImage, x-image.getWidth()/2, y-image.getHeight()/2, p);

Edit:

Using latitude and longitude coordinates to find a bearing is more difficult than simply between two points. This code however (modified from code found here) works well:

public void setBearing(Location one, Location two){
  double lat1 = one.getLatitude();
  double lon1 = one.getLongitude();
  double lat2 = two.getLatitude();
  double lon2 = two.getLongitude();
  double deltaLon = lon2-lon1;
  double y = Math.sin(deltaLon) * Math.cos(lat2);
  double x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(deltaLon);
  bearing = (float) Math.toDegrees(Math.atan2(y, x));
}
Phil
  • 35,852
  • 23
  • 123
  • 164

3 Answers3

2

To correctly compute the angle with a minimum of fuss and division by zero risks, atan2() should be preferred to atan(). The following function returns the angle relative to the x-axis of a non-zero vector from a to b:

public float getBearing(Point a, Point b) { // Valid for a != b.
    float dx = b.x - a.x;
    float dy = b.y - a.y;
    return (float)Math.atan2(dy, dx);
}

I can't give advice on how to rotate the bitmap by a given angle, since I am not familiar with your API.

antonakos
  • 8,261
  • 2
  • 31
  • 34
  • Thanks for the feedback. I was wondering how to use atan2, so this was very helpful. – Phil May 24 '11 at 12:30
  • antonakos, atan2 is the correct way to do it, but since I am using lat/long coordinates, it made the problem more difficult. To post the code, I will update my post above to add this bearing code. Thanks for your help – Phil May 24 '11 at 14:40
2

Here is how to rotate a bitmap: Android: How to rotate a moving animated sprite based on the coordinates of its destination

Community
  • 1
  • 1
Lumis
  • 21,517
  • 8
  • 63
  • 67
  • Thanks for the link. Do you know - is angle in degrees East of North, or is it in Radians (or is it something else)? – Phil May 24 '11 at 12:30
  • Angle is in degrees, the rest you will easily find after you try it. – Lumis May 24 '11 at 13:54
  • Great, simple solution! Additionally, one reason why my bearing code doesn't work is that I am working with latitude/longitude coordinates. I found an easy fix for this (I'll update my post). – Phil May 24 '11 at 14:38
  • Cool, I'll have to favorite this for later when I need it. I see you have found Math.toDegrees() function - good to know. Does your atan2 produces angles from 0-90 or 0-360? I had to adjust this manually in my link. – Lumis May 24 '11 at 15:47
  • Looks like my angles go from -180 to 180, which really makes this easy. – Phil May 24 '11 at 20:24
  • Great, in that case atan2 is the law! :) – Lumis May 24 '11 at 20:38
0

in case you want to rotate ImageView

private void rotateImage(ImageView imageView, double angle) {

    Matrix matrix = new Matrix();
    imageView.setScaleType(ScaleType.MATRIX); // required
    matrix.postRotate((float) angle, imageView.getDrawable().getBounds()
            .width() / 2, imageView.getDrawable().getBounds().height() / 2);
    imageView.setImageMatrix(matrix);
}
Nayanesh Gupte
  • 2,735
  • 25
  • 37