Search code examples
javageospatialpolar-coordinates

Calculate angle(s) between 2 positions in cartesian or polar coordinate system


I'm trying to build an ISS-Tracker without a library... So far so good. However i got the coordinates of the iss using this site: https://api.wheretheiss.at/v1/satellites/25544

From the latitude and longitude in now need to calculate two angles: Angle one is the elevation above ground 0-180° for a servo. Angle two is the rotation respective to north pole for a stepper motor (0-360°).

I already have some Java code to try it out but it won't work. I'm getting strange results. E.g: The ISS is directly above me (400km; same longitude and latitude) and the angles im getting are: 141.68° and 135.28°

Ps: Hence this is a school project using a library is not an option...

public class Main {
public static void main(String[] args) {
    //double issR = 6371 + 410.92521771305;
    double issR = 6741;
    double issLat = 58.190897;
    double issLong = -30.585309;

    //posR = height in km + earth radius
    //posLat = position latitude in °(deg)
    //posLong = position longitude in °(deg)
    double posR = 6365.092;
    double posLat = 58.190897;
    double posLong = -30.585309;

    //Convert to cartesian
    double issX = issR * Math.sin(issLat) * Math.cos(issLong);
    double issY = issR * Math.sin(issLat) * Math.sin(issLong);
    double issZ = issR * Math.cos(issLat);

    System.out.println("ISS\nx: " + issX);
    System.out.println("y: " + issY);
    System.out.println("z: " + issZ);

    //Convert to cartesian
    double posX = posR * Math.sin(posLat) * Math.cos(posLong);
    double posY = posR * Math.sin(posLat) * Math.sin(posLong);
    double posZ = posR * Math.cos(posLat);

    System.out.println("\nPOS\nx: " + posX);
    System.out.println("y: " + posY);
    System.out.println("z: " + posZ);

    //Calculate angle (I'm not sure which angle is which :D)
    double angleYZ = Math.atan2(issY - posY, issZ - posZ)*180/Math.PI;
    double angleYX = Math.atan2(issY - posY, issX - posX)*180/Math.PI;

    //Another try to calculate the angle...
    double angle = Math.toDegrees(Math.atan2(Math.sqrt(Math.pow(issX - posX, 2) + Math.pow(issY - posY, 2)), issZ - posZ))+90d;
    double angle2 = Math.toDegrees(Math.atan2(Math.sqrt(Math.pow(issX - posX, 2) + Math.pow(issY - posY, 2)), issX - posX))+90d;

    System.out.println();
    System.out.println("Angle X: " + angleYZ);
    System.out.println("Angle Z: " + angleYX);
    System.out.println(angle);
    System.out.println(angle2);
}
}

class Math {
final static double PI = java.lang.Math.PI;

public static double cos(double x) {
    return java.lang.Math.cos(x * Math.PI/180.0);
}

public static double sin(double x) {
    return java.lang.Math.sin(x * Math.PI/180.0);
}

public static double atan2(double x, double y) {
    return java.lang.Math.atan2(x, y);
}

public static double toDegrees(double angrad) {
    return java.lang.Math.toDegrees(angrad);
}

public static double pow(double a, double b) {
    return java.lang.Math.pow(a, b);
}

public static double sqrt(double a) {
    return java.lang.Math.sqrt(a);
}
}

Solution

  • This works for me as suggested by Ian Abbott:

    double tilt = Math.toDegrees(Math.atan2(issR * Math.cos(issLat - posLat) - posR, issR * Math.sin(issLat - posLat)));
    double pan = Math.toDegrees(Math.atan2(issR * Math.sin(issLong - posLong), issR * Math.cos(issLong - posLong) - posR));