I typed the compass example from "Sams Teach Yourself iPhone Application Development in 24 Hours" that is supposed to point me to the direction of Chapel Hill, N. Carolina in US. I am in Europe, so I expected it to point to the west, but is pointing somewhere north instead.
I even tried the original project that can be downloaded and it works the same. The code can be downloaded here, it is in the chapter 22 folder, ChapelHill project.
The problem could be with the method that calculates heading for a location from current location. Maybe there's somethin related with radians and degrees.
That was the algorithm, and here's the actual code:
That method is then used in this compass delegate:
Can someone please point me to some sort of a solution.
EDIT: And I am running this code on my 3Gs, original Compass application seem to work ok, Maps can locate me just fine.
I even tried the original project that can be downloaded and it works the same. The code can be downloaded here, it is in the chapter 22 folder, ChapelHill project.
The problem could be with the method that calculates heading for a location from current location. Maybe there's somethin related with radians and degrees.
Code:
/*
* According to Ask Dr. Math:
* http://mathforum.org/library/drmath/view/55417.html
*
* y = sin(lon2-lon1)*cos(lat2)
* x = cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(lon2-lon1)
* if y > 0 then
* if x > 0 then tc1 = arctan(y/x)
* if x < 0 then tc1 = 180 - arctan(-y/x)
* if x = 0 then tc1 = 90
* if y < 0 then
* if x > 0 then tc1 = -arctan(-y/x)
* if x < 0 then tc1 = arctan(y/x)-180
* if x = 0 then tc1 = 270
* if y = 0 then
* if x > 0 then tc1 = 0
* if x < 0 then tc1 = 180
* if x = 0 then [the 2 points are the same]
*/
Code:
-(double)headingToLocation:(CLLocationCoordinate2D)desired
current:(CLLocationCoordinate2D)current {
// Gather the variables needed by the heading algorithm
double lat1 = current.latitude;
double lat2 = desired.latitude;
double lon1 = current.longitude;
double lon2 = desired.longitude;
double y = sin(lon2-lon1)*cos(lat2);
double x = cos(lat1)*sin(lat2) - sin(lat1)*cos(lat2)*cos(lon2-lon1);
double heading = -1;
if (y > 0) {
if (x > 0) heading = atan(y/x);
else if (x < 0) heading = 180 - atan((-1 * y)/x);
else heading = 90;
} else if (y < 0) {
if (x > 0) heading = -1 * atan((-1 * y)/x);
else if (x < 0) heading = atan(y/x) - 180;
else heading = 270;
} else {
if (x > 0) heading = 0;
else heading = 180;
}
return heading;
}
That method is then used in this compass delegate:
Code:
- (void)locationManager:(CLLocationManager *)manager
didUpdateHeading:(CLHeading *)newHeading {
if (self.recentLocation != nil && newHeading.headingAccuracy >= 0) {
CLLocation *chapelHill = [[[CLLocation alloc]
initWithLatitude:kChapelHillLatitude
longitude:kChapelHillLongitude] autorelease];
double course = [self headingToLocation:chapelHill.coordinate
current:recentLocation.coordinate];
double delta = newHeading.trueHeading - course;
if (abs(delta) <= 10) {
directionArrow.image = [UIImage imageNamed:@"up_arrow.png"];
} else {
if (delta > 180) directionArrow.image =
[UIImage imageNamed:@"right_arrow.png"];
else if (delta > 0) directionArrow.image =
[UIImage imageNamed:@"left_arrow.png"];
else if (delta > -180) directionArrow.image =
[UIImage imageNamed:@"right_arrow.png"];
else directionArrow.image = [UIImage imageNamed:@"left_arrow.png"];
}
directionArrow.hidden = NO;
} else {
directionArrow.hidden = YES;
}
}
Can someone please point me to some sort of a solution.
EDIT: And I am running this code on my 3Gs, original Compass application seem to work ok, Maps can locate me just fine.