hmm.. Have you checked the numerical values that you get (mHeading, mBearing, angleDegrees) ? Log them and check if they look reasonable (assuming that you know where north is :). Expect some deviation caused by your surroundings. Not only the Earth is magnetic...
If that looks ok, I'd suggest to recehck your line drawing code. I took a simpler way (having some arrow bitmap to draw): Drawable d = get_your_bitmap(); canvas.save(); canvas.rotate(angleDegrees, centerX, centerY); d.draw(canvas); canvas.restore(); BR Per On 22 Sep., 18:17, Pedro Teixeira <[email protected]> wrote: > Per can you explain your example a little bit further? > My code seems fine but the direction of the arrow doesnt seem accurate: > > public void onSensorChanged(SensorEvent event) { > double mLatitude = (mLocation.getLatitude()); // lat1 location > manager > double mLongitude = (mLocation.getLongitude()); // long1 locationg > manager > double picLatitude = Double.parseDouble(picLatitudeString); //lat2 > fixed > double picLongitude = Double.parseDouble(picLongitudeString); //long2 > > fixed > float mHeading = event.values[0]; // azimuth value > float[] results = new float[1]; > Location.distanceBetween(mLatitude, mLongitude, picLatitude, > picLongitude, results); > float mBearing = results[1]; // bearing > float angleDegrees = ((mBearing - mHeading)+360) % 360; > > myCompass.updateDirection(angleDegrees); > > } > > The update method goes simply like this: > > public void updateDirection(float dir) > { > firstDraw = false; > direction = dir; > invalidate(); > } > > And this is how I draw the compass: > > public static class compassLook extends View { > > private Paint paintPointer = new Paint(Paint.ANTI_ALIAS_FLAG); > private Paint paintCircle = new Paint(Paint.ANTI_ALIAS_FLAG); > private Paint paintLeters = new Paint(Paint.ANTI_ALIAS_FLAG); > private boolean firstDraw; > private float direction; > > protected void onDraw(Canvas canvas) { > int cxCompass = (getMeasuredWidth()/2); > int cyCompass = (getMeasuredHeight()/2); > float radiusCompass; > if(cxCompass > cyCompass){ > radiusCompass = (float) (cyCompass * 0.9); > } > else{ > radiusCompass = (float) (cxCompass * 0.9); > } > // circle drawing > canvas.drawCircle(cxCompass, cyCompass, radiusCompass, > paintCircle); > if(!firstDraw){ > > // line pointer > canvas.drawLine(cxCompass, cyCompass, > (float)(cxCompass + radiusCompass * > Math.sin((double)(-direction) > * 3.14/180)), > (float)(cyCompass - radiusCompass * > Math.cos((double)(-direction) > * 3.14/180)), > paintPointer); > double mLatitude = (mLocation.getLatitude()); //lat1 > double mLongitude = > (mLocation.getLongitude());//long1 > double picLatitude = > Double.parseDouble(picLatitudeString); //lat2 > double picLongitude = > Double.parseDouble(picLongitudeString); //long2 > > // Distance formula (harversin) > float R = 6371; // km > float dLat = (float) > Math.toRadians(picLatitude-mLatitude); > float dLon = (float) > Math.toRadians((picLongitude-mLongitude)); > float a = (float) (Math.sin(dLat/2) * > Math.sin(dLat/2) + > Math.cos(Math.toRadians(mLatitude)) * Math.cos > (Math.toRadians(picLatitude)) * > Math.sin(dLon/2) * Math.sin(dLon/2)); > float c = (float) (2 * Math.atan2(Math.sqrt(a), > Math.sqrt(1-a))); > float distancia = R * c; > > canvas.drawText(String.valueOf(distancia*1000) + "m", > cxCompass-30, > cyCompass+20, paintLeters); > } > > } > > I didn't wrote all the methods on compssLook since they are not > relevant.. > > On Sep 22, 2010, at 1:12 PM, Per wrote: > > > > > > > this works for me: > > > 1: listen to location changes. Store the most recent location. You > > need it below. > > 2: listen to orientation changes. Store the most recent heading > > (azimuth) in mHeading - that's the compass direction corresponding to > > your viewing direction when holding your phone horizontally in > > portrait mode; > > 3: the bearing to your destination (assuming you have its coordinates) > > can be found using Location.distanceBetween() (call it mBearing) > > 4: to point your directional arrow towards the destination, its > > required rotation (from 'up') is ((mBearing - mHeading)+360) % 360; > > > You may wish to compensate for device rotation (portrait/landscape), > > too. See Display.getOrientation / Display.getRotation > > > Not a complete 3D solution, but works ok. > > > /Per > > > (not sure if the terms bearing/heading are 100% in sync with common > > naval use, but hey...) > > > On 22 Sep., 11:28, Kostya Vasilyev <[email protected]> wrote: > >> Pedro, > > >> I think you should learn something about the way direction (and > >> orientation) is specified in computer programming. > > >>http://en.wikipedia.org/wiki/Yaw,_pitch,_and_roll > > >>http://en.wikipedia.org/wiki/Euler_angles > > >>http://en.wikipedia.org/wiki/Rotation_representation_(mathematics)#Ro... > > >> I believe that Android orientation sensors work this way. > > >> Now about the compass.... > > >> There are two ways you can think about this: > > >> First, take the value you get from the algorithm and make it into a > >> vector in 3D space (i.e. think of the arrow you're going to draw to > >> indicate direction). Then: > > >> One: Compute the device's orientation matrix using sensor data. > >> Take the > >> inverse of this matix, and multiply the "arrow" vector by this > >> matrix. > > >> Two: Compute the device's orientation matrix using sensor data. > >> Rather > >> than interpreting it as a rotation matrix, think of it as defining a > >> plane in space (aligned with the device's screen). Then project the > >> "arrow" vector onto this plane, in the plane's coordinates. > > >> You might want to start with compensating just for the vertical axis > >> (the device's rotation from the true north direction), it might be > >> enough. > > >> -- Kostya > > >> 22.09.2010 13:02, Pedro Teixeira пишет: > > >>> I'm really not understanding how to go with this... > > >>> I've been reading and reading.. I can find all kind of > >>> algorithms.. I > >>> can find a haversin algorithm that points me to the correct > >>> direction > >>> if my device is pointing north.. but the needle is static... so if i > >>> change the device orientation the measure is incorrect... and I know > >>> this happens because I'm not using device's sensor values like > >>> azimuth, pitch and roll.. oh god.. 2 weeks on this.. I'm just > >>> desperate now. > > >>> On Sep 18, 2010, at 10:29 AM, Kostya Vasilyev wrote: > > >>>> Pedro, > > >>>> If I understand you correctly, you are having difficulties with the > >>>> device's orientation. > > >>>> The bearing angle seems to be computed in the horizontal plane. If > >>>> you wish to adjust for the device's orientation, you need to > >>>> concatenate it with the bearing angle. > > >>>> Google for "quaternions". > > >>>> This is a (relatively) simple math technique to work with rotations > >>>> the same way you can work with vectors: add / subtract, > >>>> interpolate. > > >>>> -- Kostya > > >>>> 18.09.2010 0:56, Pedro Teixeira пишет: > >>>>> Hi everyone... > > >>>>> I'm back with the same issue for the last couple of days… I'm > >>>>> trying > >>>>> to create a compass for my application BUT the difference is that, > >>>>> instead of having a line always pointing to north, I want this > >>>>> line to > >>>>> point for a specific point. I've been trying dozens of > >>>>> algorithms and > >>>>> nothing works.. > >>>>> I've finally found one that points me exactlly to the point I > >>>>> want.. > >>>>> BUT it doesn't move if I change the position of the device which > >>>>> is my > >>>>> objective.. basicly, what I want is that no matter the direction > >>>>> I'm > >>>>> using my device.. the line always point me to the point > >>>>> (picLatitude,picLongitude)… > > >>>>> I understood that for the line to move, I can't use static > >>>>> variables… > >>>>> I need to use the values offered by the onSensorChanged > >>>>> (SensorEvent > >>>>> event). > > >>>>> This are the data I have available: > > >>>>> event.values[0]: azimuth, rotation around the Z axis (device in > >>>>> relation to north, 0º) > >>>>> event.values[1]: pitch, rotation around the X axis > >>>>> event.values[2]: roll, rotation around the Y axis > >>>>> mLatitude: device current latitude gottern from GPS (variable) > >>>>> mLongitude: device current longitude gotten from GPS (variable) > >>>>> picLatitude: static picture latitude established previously > >>>>> picLongitude: static picture longitude established previously > >>>>> distance: distance in Km from device to the picture calculated > >>>>> previously > > >>>>> And this the formula that works correct, and gives me the correct > >>>>> angle.. ( BUT IT DOESN'T USE ANY OF THE SENSOR DATA SO THE LINE > >>>>> COMPASS DOESNT MOVE): > > >>>>> double dLong = picLongitude - mLongitude; > >>>>> double y = (Math.sin(dLong) * Math.cos(picLatitude)); > >>>>> double x = (Math.cos(mLatitude) * Math.sin(picLatitude) - > >>>>> Math.sin(mLatitude)*Math.cos(picLatitude)*Math.cos(dLong)); > >>>>> double angleDegreesWrongRange = Math.abs(Math.toDegrees > >>>>> (Math.atan2(y, > >>>>> x))); > >>>>> float angleDegrees = (float) ((angleDegreesWrongRange+360) % 360); > > >>>>> myCompass.updateDirection(angleDegrees); > > >>>>> I got this "bearing" formula from this website: > >>>>>http://www.movable-type.co.uk/scripts/latlong.html > > >>>>> Can someone please help me with this? > >>>>> I've try adding, subtracting… the azimuth.. I've tried with the > >>>>> others.. seriously at this point I'm just demoralized.. > > >>>>> Thank you in advance > > >>>> -- > >>>> Kostya Vasilyev -- WiFi Manager + pretty widget -- > >>>>http://kmansoft.wordpress.com > > >>>> -- > >>>> You received this message because you are subscribed to the Google > >>>> Groups "Android Developers" group. > >>>> To post to this group, send email to [email protected] > >>>> To unsubscribe from this group, send email to > >>>> [email protected] > >>>> For more options, visit this group at > >>>>http://groups.google.com/group/android-developers?hl=en > > >>> Pedro Teixeira > > >>>www.pedroteixeira.org > > >> -- > >> Kostya Vasilyev -- WiFi Manager + pretty widget > >> --http://kmansoft.wordpress.com > > > -- > > You received this message because you are subscribed to the Google > > Groups "Android Developers" group. > > To post to this group, send email to [email protected] > > To unsubscribe from this group, send email to > > [email protected] > > For more options, visit this group at > >http://groups.google.com/group/android-developers?hl=en > > Pedro Teixeira > > www.pedroteixeira.org -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en

