package gov.sandia.gnem.slbmjni;

import static java.lang.Math.atan;
import static java.lang.Math.cos;
import static java.lang.Math.sin;
import static java.lang.Math.tan;
import static java.lang.Math.toRadians;

public class Point
{
    public double[] u;

    /**
     * Point constructor
     * @param lat in degrees or radians
     * @param lon in degrees or radians
     * @param inDegrees if true, then lat,lon are assumed to be in degrees
     * otherwise radians
     */
    public Point(double lat, double lon, boolean inDegrees)
    {
        u = inDegrees ? getVector(toRadians(lat), toRadians(lon)) : getVector(lat, lon);
    }

    public Point(GridProfile profile)
    {
        this(profile.lat, profile.lon, false);
    }

    @Override
    public boolean equals(Object other)
    {
        return dot(u, ((Point)other).u) > cos(1e-7);
    }

    @Override
    public int hashCode() { return (int)(u[2]*1e4); }

    public static double dot(double[] v0, double[] v1)
    { return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2]; }

    /**
     * Convert geographic lat, lon into a geocentric unit vector. The
     * x-component points toward lat,lon = 0, 0. The y-component points toward
     * lat,lon = 0, PI/2. The z-component points toward north pole.
     *
     * @param lat
     *            geographic latitude in radians.
     * @param lon
     *            longitude in radians.
     * @return 3 component unit vector.
     */
    public static double[] getVector(double lat, double lon)
    {
        double[] vector = new double[3];
        getVector(lat, lon, vector);
        return vector;
    }

    /**
     * Convert geographic lat, lon into a geocentric unit vector. The
     * x-component points toward lat,lon = 0, 0. The y-component points toward
     * lat,lon = 0, PI/2 The z-component points toward north pole.
     *
     * @param lat
     *            geographic latitude in radians.
     * @param lon
     *            longitude in radians.
     * @param vector
     *            3 component unit vector.
     */
    public static void getVector(double lat, double lon, double[] vector)
    {
        lat = atan(0.9933056199770992 * tan(lat));

        // z component of v is sin of geocentric latitude.
        vector[2] = sin(lat);

        // set lat = to cos of geocentric latitude
        lat = cos(lat);

        // compute x and y components of v
        vector[0] = lat * cos(lon);
        vector[1] = lat * sin(lon);
    }

}

