package com.o3dr.services.android.lib.util;
import com.o3dr.services.android.lib.coordinate.LatLong;
import com.o3dr.services.android.lib.coordinate.LatLongAlt;
import junit.framework.TestCase;
import java.util.Random;
/**
* Unit tests for math utility functions.
*/
public class MathUtilsTest extends TestCase {
private static final int MIN_LATITUDE = -90;
private static final int MAX_LATITUDE = 90;
private static final int MIN_LONGITUDE = -180;
private static final int MAX_LONGITUDE = 180;
private static final double MARGIN_OF_ERROR = 3; //3 Meters
/**
* The following constants where obtained from NOAA and are used to validate the
* accuracy of our methods
*/
//Using berkley as the origin
private static final double originLat = 37.8715926;
private static final double originLon = -122.27274699999998;
//Points where obtained from google maps and distance was calculated from
//http://www.nhc.noaa.gov/gccalc.shtml
private static final double FIRST_LAT = 37.875074;
private static final double FIRST_LON = -122.273347;
private static final double FIRST_RESULT = 390.0146608686402;
private static final double SECOND_LAT = 37.875311;
private static final double SECOND_LON = -122.278068;
private static final double SECOND_RESULT = 624.1308042182045;
private static final double THIRD_LAT = 37.871686;
private static final double THIRD_LON = -122.270451;
private static final double THIRD_RESULT = 202.2891830637083;
public void testGetDistance3D() throws Exception {
//Test get distance altitude only.
double distance = MathUtils.getDistance3D(new LatLongAlt(0.0, 0.0, 50.0), new LatLongAlt(0.0, 0.0, 100.0));
assertEquals(distance, 50.0, MARGIN_OF_ERROR);
}
public void testGetDistance2D() throws Exception {
//Test get distance with Noaa values
LatLong origin = new LatLong(originLat, originLon);
assertEquals(FIRST_RESULT, MathUtils.getDistance2D(origin, new LatLong(FIRST_LAT, FIRST_LON)), MARGIN_OF_ERROR);
assertEquals(SECOND_RESULT, MathUtils.getDistance2D(origin, new LatLong(SECOND_LAT, SECOND_LON)), MARGIN_OF_ERROR);
assertEquals(THIRD_RESULT, MathUtils.getDistance2D(origin, new LatLong(THIRD_LAT, THIRD_LON)), MARGIN_OF_ERROR);
}
public void testGetDistance() throws Exception {
// Validate that both the 2D and 3D generate the same result when distance is disregarded.
double distance1;
double distance2;
double fromLatitude;
double fromLongitude;
double toLatitude;
double toLongitude;
Random rand = new Random();
//Generate 500 random locations and test both equations
for (int index = 0; index < 500; index++){
fromLatitude = randDouble(rand, MIN_LATITUDE, MAX_LATITUDE);
fromLongitude = randDouble(rand, MIN_LONGITUDE, MAX_LONGITUDE);
toLatitude = randDouble(rand, MIN_LATITUDE, MAX_LATITUDE);
toLongitude = randDouble(rand, MIN_LONGITUDE, MAX_LONGITUDE);
//3D Distance equation
distance1 = MathUtils.getDistance3D(new LatLongAlt(fromLatitude, fromLongitude, 0.0), new LatLongAlt(toLatitude, toLongitude, 0.0));
//2D Distance equation
distance2 = MathUtils.getDistance2D(new LatLong(fromLatitude, fromLongitude), new LatLong(toLatitude, toLongitude));
//Assert that the results from both equations are equal
assertEquals(distance1, distance2, MARGIN_OF_ERROR);
}
}
/**
* Returns a pseudo-random number between min and max, inclusive.
* The difference between min and max can be at most
*
* @param min Minimum value
* @param max Maximum value. Must be greater than min.
* @return Double between min and max, inclusive.
* @see java.util.Random#nextInt(int)
*/
private double randDouble(Random rand, int min, int max) {
// nextDouble is normally exclusive of the top value,
// so add 1 to make it inclusive
return (rand.nextDouble() * (max - min)) + min;
}
public void testNormalize() {
double max = 10;
double min = 0;
assertEquals(0.0, MathUtils.normalize(0, min, max));
assertEquals(0.5, MathUtils.normalize(5, min, max));
assertEquals(1.0, MathUtils.normalize(10, min, max));
assertEquals(0.0, MathUtils.normalize(-1, min, max));
assertEquals(1.0, MathUtils.normalize(100, min, max));
}
public void testIfCanCreateObject() {
assertNotNull(new MathUtils());
}
public void testDCMmatrix(){
double [][] dcm = MathUtils.dcmFromEuler(0,0,0);
double [][] expected = new double[][] {{1,0,0},{0,1,0},{0,0,1}};
for (int i = 0; i < dcm.length; i++) {
for (int j = 0; j < dcm.length; j++) {
assertEquals(expected[i][j], dcm[i][j],1e-10);
}
}
}
}