Take the 2-minute tour ×
Mathematics Stack Exchange is a question and answer site for people studying math at any level and professionals in related fields. It's 100% free, no registration required.

This is a practical question, so if you find something missing, please assume a real life scenario.

The question is related to GPS and the Earth.

lat1: my latitude, GPS position I'm standing at (degrees)
lon1: my longitude, GPS position I'm standing at (degrees)
dir1: my direction I'm facing (from north, 0-360°, positive clockwise)
lat2: latitude of object
lon2: longitude of object
view: my viewport

I'm a person with position lat1, lon1, facing dir1. My viewport is 180°. Object is located at lat2, lon2.

How do I calculate that object is within my viewport?

Edit: viewport is assumed to be 180° and has a 1km radius.

share|improve this question
1  
Do you assume that you can see over the horizon? Any limit to that? –  John M Jul 24 '11 at 4:49
    
I guess you could post your calculations, but before you do that, I'd check to make sure how well-posed your problem is. The way I see it, if you have a 180 degree view, but there is no limit to how far you can see, then you should be able to see any point on the globe, just by following a great circle route. So I would say the answer is that every object is in your viewport. –  John M Jul 24 '11 at 6:32
3  
@bizso09: Since you mention the frustrating waste of your time, you will probably be able to appreciate that the downvoters are frustrated about the waste of their time by scores of sloppily posed questions where one realizes after taking the time to read through them and think about them that the person who posed them didn't take the time and care to make sure all the relevant information is included. You've now further exacerbated that by forcing them to read through long comments before they get to an essential piece of information; you should edit that into the question. –  joriki Jul 24 '11 at 7:54
1  
@bizso09: I don't know from which part of my comment you inferred that I don't understand the question. I wasn't criticizing long comments in general, but hiding crucial information about the question among long comments. I hadn't downvoted your question before, but I did now after your reaction. You still haven't added the viewport radius to the question after having noticed its omission and being alerted to the fact that it should be in the body of the question. Your chances of getting useful answers from the community will increase considerably if you show more respect to it. –  joriki Jul 24 '11 at 9:50
2  
@bizso09: It's fairly standard here to let people you don't know edit their own questions if they know how they should. Downvotes are a symbolic action designed to grade a user's effort and sincerity behind a post; joriki's action fulfilled that purpose faithfully. It's always the OP's responsibility to craft & improve any post - if he/she leaves it to the comment section they disservice readers. Taking the time to explain these things to newcomers is a separate affair. That said, I truly do understand the aggravation of lonely, grueling calculations - we've all been there. Live and learn bro. –  anon Jul 24 '11 at 10:27

2 Answers 2

Read up on vectors if you are not already into the subject.

Translation from coordinates to unit vectors (vectors of length 1), where the origin is centre of the Earth, X-axis points to N0,E0, Y-axis points to N0,E90 and Z-axis points to the North pole:

posX=cos(lon)*cos(lat)
posY=sin(lon)*cos(lat)
posZ=sin(lat)

faceNorthX=-cos(lon)*sin(lat)
faceNorthY=-sin(lon)*sin(lat)
faceNorthZ=cos(lat)

faceEastX=-sin(lon)
faceEastY=cos(lon)
faceEastZ=0

faceDir=faceNorth*cos(dir)+faceEast*sin(dir)

Now if

dotProduct(faceDir1,pos2-pos1)

is positive, then you are according to your definition facing pos2 from pos1.

More general

dotProduct(vector1,vector2) / (length(vector1) * length(vector1))

is cosine of the angle between the vectors.

This is useful for calculating the surface distance between two points, since the vectors generated so far are all unit vectors the expression can be simplified a bit for this use.

surfaceDistance=Earth.radius*arccos(dotProduct(pos1,pos2))

The direct distance is simply

directDistance=Earth.radius*length(pos2-pos1)
share|improve this answer

Ok folks, this is what I could come up with in 4 hours LOL. Could any of you please check that this is correct? Probably I'll write a bunch of unit tests anyway, but I'm so confused...

public class GpsPosition {

private double              mLatitude;
private double              mLongitude;
private double              mDirection;

public boolean isInViewport(GpsPosition otherPos) {
    double otherDir = directionTowards(otherPos);
    double range = VIEWPORT_DEGREE / 2;
    double minRange = mDirection - range;
    double maxRange = mDirection + range;

    if (minRange < 0) {
        minRange = 360 + minRange;
        if (otherDir >= minRange) {
            return true;
        } else if (otherDir <= maxRange) {
            return true;
        } else {
            return false;
        }
    } else if (maxRange > 360) {
        maxRange = maxRange - 360;
        if (otherDir <= maxRange) {
            return true;
        } else if (otherDir >= minRange) {
            return true;
        } else {
            return false;
        }
    } else if (minRange >= 0 && maxRange <= 360) {
        if (otherDir <= maxRange && otherDir >= minRange) {
            return true;
        } else {
            return false;
        }
    } else {
        throw new AssertionError("I'm sorry, Dave, I'm afraid I can't do that.");
    }

}

double directionTowards(GpsPosition otherPos) {
    GpsPosition northPole = new GpsPosition(90,0,0);
    double a = distanceTo(otherPos);
    double b = distanceTo(northPole);
    double c = otherPos.distanceTo(northPole);

    //Laws of cosines
    double gamma = Math.acos((a*a + b*b - c*c)/(2*a*b));

    boolean negative = (otherPos.mLongitude - mLongitude) < 0;//potential bug at 180° longitude, ignore for now
    if (negative) {
        gamma = 360 - gamma;
    }
    return gamma;

}

double distanceTo(GpsPosition otherPos) {

    double R = EARTH_PERIMETER; //6371.0 km
    double lat1 = mLatitude;
    double lon1 = mLongitude;
    double lat2 = otherPos.mLatitude;
    double lon2 = otherPos.mLongitude;


    double dLat = Math.toRadians(lat2-lat1);
    double dLon = Math.toRadians(lon2-lon1);
    lat1 = Math.toRadians(lat1);
    lat2 = Math.toRadians(lat2);

    //Haversine formula
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
            Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
    double d = R * c;
    return d;
}
}
share|improve this answer
2  
You do realize that the law of cosines on the surface of a sphere does not hold, don't you? The larger the triangle, the more troubling it will be. Another consideration would be that your quantities b and c are essentially equal so by calculating the difference of there square loses a lot of accuracy. If your viewport radius will always be small in comparison to the Earth's radius (say less than 10 km, depends on how many significatn digits you want), then you can view the surface is locally flat, and simply calculate NS and EW displacements from the longitude and latitude differences. –  Jyrki Lahtonen Jul 24 '11 at 12:11
1  
@bizs009: As a rule of thumb, I think that posts on a non-programming site should not require the reader to understand a programming language (or even pseudocode). I certainly do not, and as a result I have no clue what your answer says (eBusiness's post is essentially intelligible, although the wordy variable names still throw me off). If you are able to implement an answer in code, surely you are also able to describe it using mathematics, and I think math is the better option in terms of accessibility. –  Zev Chonoles Jul 24 '11 at 14:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.