Disabled external gits
167
Alpano/tests/ch/epfl/alpano/AzimuthTest.java
Normal file
@@ -0,0 +1,167 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
import static ch.epfl.alpano.Azimuth.canonicalize;
|
||||
import static ch.epfl.alpano.Azimuth.fromMath;
|
||||
import static ch.epfl.alpano.Azimuth.isCanonical;
|
||||
import static ch.epfl.alpano.Azimuth.toMath;
|
||||
import static ch.epfl.alpano.Azimuth.toOctantString;
|
||||
import static ch.epfl.test.TestRandomizer.RANDOM_ITERATIONS;
|
||||
import static ch.epfl.test.TestRandomizer.newRandom;
|
||||
import static java.lang.Math.PI;
|
||||
import static java.lang.Math.floorMod;
|
||||
import static java.lang.Math.nextDown;
|
||||
import static java.lang.Math.round;
|
||||
import static java.lang.Math.scalb;
|
||||
import static java.lang.Math.toDegrees;
|
||||
import static java.lang.Math.toRadians;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class AzimuthTest {
|
||||
@Test
|
||||
public void isCanonicalIsTrueFor0() {
|
||||
assertTrue(isCanonical(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isCanonicalIsFalseFor0Pred() {
|
||||
assertFalse(isCanonical(nextDown(0)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isCanonicalIsTrueFor2PiPred() {
|
||||
assertTrue(isCanonical(nextDown(scalb(PI, 1))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isCanonicalIsFalseFor2Pi() {
|
||||
assertFalse(isCanonical(scalb(PI, 1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isCanonicalIsTrueForRandomCanonicalAzimuths() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i)
|
||||
assertTrue(isCanonical(rng.nextDouble() * scalb(PI, 1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canonicalizeCorrectlyCanonicalizesRoundedRandomAngles() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
int aDeg = rng.nextInt(10_000) - 5_000;
|
||||
double aRad = toRadians(aDeg);
|
||||
double canonicalARad = canonicalize(aRad);
|
||||
assertTrue(0 <= canonicalARad && canonicalARad < scalb(PI, 1));
|
||||
int canonicalADeg = (int)round(toDegrees(canonicalARad));
|
||||
if (canonicalADeg == 360)
|
||||
canonicalADeg = 0;
|
||||
assertEquals(floorMod(aDeg, 360), canonicalADeg);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toMathCorrectlyHandles0() {
|
||||
assertEquals(0d, toMath(0d), 0d);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromMathCorrectlyHandles0() {
|
||||
assertEquals(0d, fromMath(0d), 0d);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toMathWorksForKnownValues() {
|
||||
int[] vs = new int[] {
|
||||
0, 0,
|
||||
1,359,
|
||||
2,358,
|
||||
358,2,
|
||||
359,1,
|
||||
90, 270,
|
||||
180, 180,
|
||||
179,181,
|
||||
181,179,
|
||||
270, 90
|
||||
};
|
||||
for (int i = 0; i < vs.length; i += 2) {
|
||||
double a = toMath(toRadians(vs[i]));
|
||||
assertEquals(toRadians(vs[i+1]), a, 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromMathWorksForKnownValues() {
|
||||
int[] vs = new int[] {
|
||||
0, 0,
|
||||
1,359,
|
||||
2,358,
|
||||
358,2,
|
||||
359,1,
|
||||
90, 270,
|
||||
180, 180,
|
||||
179,181,
|
||||
181,179,
|
||||
270, 90
|
||||
};
|
||||
for (int i = 0; i < vs.length; i += 2) {
|
||||
double a = fromMath(toRadians(vs[i]));
|
||||
assertEquals(toRadians(vs[i+1]), a, 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toMathAndFromMathAreInverseForRandomValues() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double a = rng.nextDouble() * scalb(PI, 1);
|
||||
double a2 = fromMath(toMath(a));
|
||||
assertEquals(a, a2, 1e-10);
|
||||
|
||||
double a3 = toMath(fromMath(a));
|
||||
assertEquals(a, a3, 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = java.lang.IllegalArgumentException.class)
|
||||
public void toMathThrowsFor2Pi() {
|
||||
toMath(scalb(PI, 1));
|
||||
}
|
||||
|
||||
@Test(expected = java.lang.IllegalArgumentException.class)
|
||||
public void fromMathThrowsFor2Pi() {
|
||||
fromMath(scalb(PI, 1));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void toOctantStringThrowsForNonCanonicalAzimuth() {
|
||||
toOctantString(-1, null, null, null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toOctantStringCorrectlyCyclesThroughValues() {
|
||||
String n = "north", e = "east", s = "south", w = "west";
|
||||
ArrayList<String> expected = new ArrayList<>();
|
||||
expected.addAll(Collections.nCopies(45, n));
|
||||
expected.addAll(Collections.nCopies(45, n+e));
|
||||
expected.addAll(Collections.nCopies(45, e));
|
||||
expected.addAll(Collections.nCopies(45, s+e));
|
||||
expected.addAll(Collections.nCopies(45, s));
|
||||
expected.addAll(Collections.nCopies(45, s+w));
|
||||
expected.addAll(Collections.nCopies(45, w));
|
||||
expected.addAll(Collections.nCopies(45, n+w));
|
||||
|
||||
for (int aDeg = 0; aDeg < 360; ++aDeg) {
|
||||
double aRad = toRadians(floorMod(aDeg - 22, 360));
|
||||
String os = toOctantString(aRad, n, e, s, w);
|
||||
assertEquals(expected.get(aDeg), os);
|
||||
}
|
||||
}
|
||||
}
|
37
Alpano/tests/ch/epfl/alpano/DistanceTest.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
import static ch.epfl.test.TestRandomizer.RANDOM_ITERATIONS;
|
||||
import static ch.epfl.test.TestRandomizer.newRandom;
|
||||
import static java.lang.Math.PI;
|
||||
import static java.lang.Math.scalb;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class DistanceTest {
|
||||
private static double EARTH_CIRCUMFERENCE = 40_030_174; // rounded to nearest integer
|
||||
|
||||
@Test
|
||||
public void toRadiansAndToMetersAreInverseForRandomValues() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double dRad = rng.nextDouble() * scalb(PI, 1);
|
||||
double dRad2 = Distance.toRadians(Distance.toMeters(dRad));
|
||||
assertEquals(dRad, dRad2, 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toMetersIsCorrectForKnownValues() {
|
||||
assertEquals(0, Distance.toMeters(0), 0);
|
||||
assertEquals(EARTH_CIRCUMFERENCE, Distance.toMeters(scalb(PI, 1)), 0.5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toRadiansIsCorrectForKnownValues() {
|
||||
assertEquals(0, Distance.toRadians(0), 0);
|
||||
assertEquals(scalb(PI, 1), Distance.toRadians(EARTH_CIRCUMFERENCE), 1e-5);
|
||||
}
|
||||
}
|
71
Alpano/tests/ch/epfl/alpano/DrawPanorama.java
Normal file
@@ -0,0 +1,71 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import ch.epfl.alpano.dem.ContinuousElevationModel;
|
||||
import ch.epfl.alpano.dem.DiscreteElevationModel;
|
||||
import ch.epfl.alpano.dem.HgtDiscreteElevationModel;
|
||||
|
||||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
import static java.lang.Math.toRadians;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
final class DrawPanorama {
|
||||
final static File HGT_FILE = new File("HGT"+File.separatorChar+"N46E007.hgt");
|
||||
|
||||
final static int IMAGE_WIDTH = 500;
|
||||
final static int IMAGE_HEIGHT = 200;
|
||||
|
||||
final static double ORIGIN_LON = toRadians(7.65);
|
||||
final static double ORIGIN_LAT = toRadians(46.73);
|
||||
final static int ELEVATION = 600;
|
||||
final static double CENTER_AZIMUTH = toRadians(180);
|
||||
final static double HORIZONTAL_FOV = toRadians(60);
|
||||
final static int MAX_DISTANCE = 100_000;
|
||||
|
||||
final static PanoramaParameters PARAMS =
|
||||
new PanoramaParameters(new GeoPoint(ORIGIN_LON,
|
||||
ORIGIN_LAT),
|
||||
ELEVATION,
|
||||
CENTER_AZIMUTH,
|
||||
HORIZONTAL_FOV,
|
||||
MAX_DISTANCE,
|
||||
IMAGE_WIDTH,
|
||||
IMAGE_HEIGHT);
|
||||
|
||||
public static void main(String[] as) throws Exception {
|
||||
try (DiscreteElevationModel dDEM =
|
||||
new HgtDiscreteElevationModel(HGT_FILE)) {
|
||||
ContinuousElevationModel cDEM =
|
||||
new ContinuousElevationModel(dDEM);
|
||||
Panorama p = new PanoramaComputer(cDEM)
|
||||
.computePanorama(PARAMS);
|
||||
|
||||
BufferedImage i =
|
||||
new BufferedImage(IMAGE_WIDTH,
|
||||
IMAGE_HEIGHT,
|
||||
BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
for (int x = 0; x < IMAGE_WIDTH; ++x) {
|
||||
for (int y = 0; y < IMAGE_HEIGHT; ++y) {
|
||||
float d = p.distanceAt(x, y);
|
||||
int c = (d == Float.POSITIVE_INFINITY)
|
||||
? 0x87_CE_EB
|
||||
: gray((d - 2_000) / 15_000);
|
||||
i.setRGB(x, y, c);
|
||||
}
|
||||
}
|
||||
|
||||
ImageIO.write(i, "png", new File("tests/ch/epfl/alpano/niesen.png"));
|
||||
}
|
||||
}
|
||||
private static int gray(double v) {
|
||||
double clampedV = max(0, min(v, 1));
|
||||
int gray = (int) (255.9999 * clampedV);
|
||||
return (gray << 16) | (gray << 8) | gray;
|
||||
}
|
||||
}
|
66
Alpano/tests/ch/epfl/alpano/DrawPanoramaNew.java
Normal file
@@ -0,0 +1,66 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import ch.epfl.alpano.dem.ContinuousElevationModel;
|
||||
import ch.epfl.alpano.dem.DiscreteElevationModel;
|
||||
import ch.epfl.alpano.dem.HgtDiscreteElevationModel;
|
||||
import ch.epfl.alpano.gui.ChannelPainter;
|
||||
import ch.epfl.alpano.gui.ImagePainter;
|
||||
import ch.epfl.alpano.gui.PanoramaRenderer;
|
||||
import javafx.embed.swing.SwingFXUtils;
|
||||
import javafx.scene.image.Image;
|
||||
import static java.lang.Math.toRadians;
|
||||
|
||||
final class DrawPanoramaNew {
|
||||
final static File HGT_FILE = new File("HGT"+File.separatorChar+"N46E007.hgt");
|
||||
|
||||
final static int IMAGE_WIDTH = 2_500;
|
||||
final static int IMAGE_HEIGHT = 800;
|
||||
|
||||
final static double ORIGIN_LON = toRadians(7.65);
|
||||
final static double ORIGIN_LAT = toRadians(46.73);
|
||||
final static int ELEVATION = 600;
|
||||
final static double CENTER_AZIMUTH = toRadians(180);
|
||||
final static double HORIZONTAL_FOV = toRadians(110);
|
||||
final static int MAX_DISTANCE = 100_000;
|
||||
|
||||
final static PanoramaParameters PARAMS =
|
||||
new PanoramaParameters(new GeoPoint(ORIGIN_LON,
|
||||
ORIGIN_LAT),
|
||||
ELEVATION,
|
||||
CENTER_AZIMUTH,
|
||||
HORIZONTAL_FOV,
|
||||
MAX_DISTANCE,
|
||||
IMAGE_WIDTH,
|
||||
IMAGE_HEIGHT);
|
||||
|
||||
public static void main(String[] as) throws Exception {
|
||||
try (DiscreteElevationModel dDEM =
|
||||
new HgtDiscreteElevationModel(HGT_FILE)) {
|
||||
ContinuousElevationModel cDEM =
|
||||
new ContinuousElevationModel(dDEM);
|
||||
Panorama p = new PanoramaComputer(cDEM)
|
||||
.computePanorama(PARAMS);
|
||||
|
||||
ChannelPainter d = p::distanceAt;
|
||||
ChannelPainter sl = p::slopeAt;
|
||||
ChannelPainter h = d.div(100000).cycling().mul(360);
|
||||
ChannelPainter s = d.div(200000).clamped().inverted();
|
||||
ChannelPainter b = sl.mul(2).div(Math.PI).inverted().mul(0.7).add(0.3);
|
||||
ChannelPainter o =
|
||||
d.map(dist -> dist == Float.POSITIVE_INFINITY ? 0 : 1);
|
||||
|
||||
ImagePainter l = ImagePainter.hsb(h, s, b, o);
|
||||
|
||||
Image i = PanoramaRenderer.renderPanorama(p, l);
|
||||
ImageIO.write(SwingFXUtils.fromFXImage(i, null),
|
||||
"png",
|
||||
new File("tests/ch/epfl/alpano/niesen-profile.png"));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
63
Alpano/tests/ch/epfl/alpano/DrawPanoramaNew2.java
Normal file
@@ -0,0 +1,63 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import ch.epfl.alpano.dem.ContinuousElevationModel;
|
||||
import ch.epfl.alpano.dem.DiscreteElevationModel;
|
||||
import ch.epfl.alpano.dem.HgtDiscreteElevationModel;
|
||||
import ch.epfl.alpano.gui.ChannelPainter;
|
||||
import ch.epfl.alpano.gui.ImagePainter;
|
||||
import ch.epfl.alpano.gui.PanoramaRenderer;
|
||||
import ch.epfl.alpano.gui.PanoramaUserParameters;
|
||||
import javafx.embed.swing.SwingFXUtils;
|
||||
import javafx.scene.image.Image;
|
||||
import ch.epfl.alpano.gui.PredefinedPanoramas;
|
||||
|
||||
final class DrawPanoramaNew2 {
|
||||
|
||||
public static void main(String[] as) throws Exception {
|
||||
PanoramaUserParameters pano = PredefinedPanoramas.JURA_ALPS.get();
|
||||
|
||||
ContinuousElevationModel cDEM =generatePredefinedCDEM("./HGT/");
|
||||
Panorama p = new PanoramaComputer(cDEM)
|
||||
.computePanorama(pano.panoramaComputeParameters());
|
||||
|
||||
ChannelPainter d = p::distanceAt;
|
||||
ChannelPainter sl = p::slopeAt;
|
||||
ChannelPainter h = d.div(100000).cycling().mul(360);
|
||||
ChannelPainter s = d.div(200000).clamped().inverted();
|
||||
ChannelPainter b = sl.mul(2).div(Math.PI).inverted().mul(0.7).add(0.3);
|
||||
ChannelPainter o =
|
||||
d.map(dist -> dist == Float.POSITIVE_INFINITY ? 0 : 1);
|
||||
|
||||
ImagePainter l = ImagePainter.hsb(h, s, b, o);
|
||||
|
||||
Image i = PanoramaRenderer.renderPanorama(p, l);
|
||||
ImageIO.write(SwingFXUtils.fromFXImage(i, null),
|
||||
"png",
|
||||
new File("tests/ch/epfl/alpano/niesen-profile.png"));
|
||||
|
||||
}
|
||||
|
||||
private static final ContinuousElevationModel generatePredefinedCDEM(String path){
|
||||
|
||||
DiscreteElevationModel DEM1=null;
|
||||
DiscreteElevationModel DEM2=null;
|
||||
File file;
|
||||
for(int i=6;i<=11;++i){
|
||||
for(int j=45;j<=47;++j){
|
||||
file = new File(String.format((Locale) null, path+"N%02dE%03d.hgt",j,i));
|
||||
if(DEM1==null)
|
||||
DEM1 = new HgtDiscreteElevationModel(file);
|
||||
DEM1 = new HgtDiscreteElevationModel(file).union(DEM1);
|
||||
}
|
||||
if(DEM2==null)
|
||||
DEM2=DEM1;
|
||||
DEM2=DEM1.union(DEM2);
|
||||
DEM1=null;
|
||||
}
|
||||
return new ContinuousElevationModel(DEM2);
|
||||
}
|
||||
}
|
68
Alpano/tests/ch/epfl/alpano/GeoPointTest.java
Normal file
@@ -0,0 +1,68 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class GeoPointTest {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorLimitTest1(){
|
||||
new GeoPoint(0, 2*Math.PI);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorLimitTest2(){
|
||||
new GeoPoint(2*Math.PI, 2*Math.PI);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorLimitTest3(){
|
||||
new GeoPoint(2*Math.PI, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void distanceToTest1(){
|
||||
GeoPoint london = new GeoPoint(Math.toRadians(6.631), Math.toRadians(46.521));
|
||||
GeoPoint moscow = new GeoPoint( Math.toRadians(37.623), Math.toRadians(55.753));
|
||||
assertEquals(2367000, london.distanceTo(moscow), 1000);//1km imprecision
|
||||
assertEquals(0,london.azimuthTo(london),0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void distanceToTest2(){
|
||||
GeoPoint epfl = new GeoPoint(Math.toRadians(6.56730), Math.toRadians(46.51781));
|
||||
GeoPoint eiler = new GeoPoint( Math.toRadians(8.00537), Math.toRadians(46.57756));
|
||||
assertEquals(110294, epfl.distanceTo(eiler), 150);//150M imprecision
|
||||
}
|
||||
|
||||
@Test
|
||||
public void distanceToTest3(){
|
||||
GeoPoint p1 = new GeoPoint(Math.PI,Math.PI/2.0);
|
||||
GeoPoint p2 = new GeoPoint(Math.PI,Math.PI/2.0);
|
||||
GeoPoint p3 = new GeoPoint(0,Math.PI/2.0);
|
||||
GeoPoint p4 = new GeoPoint(Math.PI/10.0,Math.PI/2.0);
|
||||
assertEquals(p3.distanceTo(p4), p4.distanceTo(p3), 10);
|
||||
assertEquals(p2.distanceTo(p1), p1.distanceTo(p2), 10);
|
||||
assertEquals(p3.distanceTo(p4), p1.distanceTo(p2), 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void distanceToTest4(){
|
||||
GeoPoint p1 = new GeoPoint(Math.PI/2.0,Math.PI/2.0);
|
||||
GeoPoint p2 = new GeoPoint(-Math.PI/2.0,Math.PI/2.0);
|
||||
GeoPoint p3 = new GeoPoint(-Math.PI/2.0,Math.PI/2.0);
|
||||
GeoPoint p4 = new GeoPoint(Math.PI/10.0,Math.PI/2.0);
|
||||
assertEquals(p3.distanceTo(p4), p4.distanceTo(p3), 10);
|
||||
assertEquals(p2.distanceTo(p1), p1.distanceTo(p2), 10);
|
||||
assertEquals(p3.distanceTo(p4), p1.distanceTo(p2), 10);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void toStringTest(){
|
||||
GeoPoint g = new GeoPoint(Math.toRadians(-7.6543), Math.toRadians(54.3210));
|
||||
assertEquals("(-7.6543,54.3210)", g.toString());
|
||||
}
|
||||
|
||||
}
|
31
Alpano/tests/ch/epfl/alpano/GeoPointTestP.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
import static java.lang.Math.toDegrees;
|
||||
import static java.lang.Math.toRadians;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class GeoPointTestP {
|
||||
private static GeoPoint CORNAVIN = new GeoPoint(toRadians(6.14308), toRadians(46.21023));
|
||||
private static GeoPoint M1_EPFL = new GeoPoint(toRadians(6.56599), toRadians(46.52224));
|
||||
private static GeoPoint FEDERAL_PALACE = new GeoPoint(toRadians(7.44428), toRadians(46.94652));
|
||||
private static GeoPoint SAENTIS = new GeoPoint(toRadians(9.34324), toRadians(47.24942));
|
||||
private static GeoPoint MONTE_TAMARO = new GeoPoint(toRadians(8.86598), toRadians(46.10386));
|
||||
|
||||
@Test
|
||||
public void distanceToWorksOnKnownPoints() {
|
||||
assertEquals(226_000, M1_EPFL.distanceTo(SAENTIS), 10);
|
||||
assertEquals( 81_890, M1_EPFL.distanceTo(FEDERAL_PALACE), 10);
|
||||
assertEquals(143_560, FEDERAL_PALACE.distanceTo(MONTE_TAMARO), 10);
|
||||
assertEquals(269_870, SAENTIS.distanceTo(CORNAVIN), 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void azimuthToWorksOnKnownPoints() {
|
||||
assertEquals( 68.03, toDegrees(M1_EPFL.azimuthTo(SAENTIS)), 0.01);
|
||||
assertEquals( 54.50, toDegrees(M1_EPFL.azimuthTo(FEDERAL_PALACE)), 0.01);
|
||||
assertEquals(130.23, toDegrees(FEDERAL_PALACE.azimuthTo(MONTE_TAMARO)), 0.01);
|
||||
assertEquals(245.82, toDegrees(SAENTIS.azimuthTo(CORNAVIN)), 0.01);
|
||||
}
|
||||
}
|
257
Alpano/tests/ch/epfl/alpano/Interval1DTest.java
Normal file
@@ -0,0 +1,257 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
import static ch.epfl.test.TestRandomizer.RANDOM_ITERATIONS;
|
||||
import static ch.epfl.test.TestRandomizer.newRandom;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class Interval1DTest {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testRandomIncludedFromAndToFails() {
|
||||
Random rng = newRandom();
|
||||
int a,b;
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i){
|
||||
a = rng.nextInt();
|
||||
b = rng.nextInt();
|
||||
if(a>b){
|
||||
new Interval1D(a,b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRandomIncludedFromAndTo() {
|
||||
Random rng = newRandom();
|
||||
Interval1D interval;
|
||||
int a,b;
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i){
|
||||
a = rng.nextInt();
|
||||
b = rng.nextInt();
|
||||
if(a<=b){
|
||||
interval = new Interval1D(a,b);
|
||||
assertEquals(interval.includedFrom(),a,0);
|
||||
assertEquals(interval.includedTo(),b,0);
|
||||
assertEquals(interval.size(),(b-a+1),0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLimitsIncludedFromAndTo() {
|
||||
|
||||
Interval1D interval = new Interval1D(0,0);
|
||||
assertEquals(interval.includedFrom(),0,0);
|
||||
assertEquals(interval.includedTo(),0,0);
|
||||
assertEquals(interval.size(),1,0);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContainsTrue() {
|
||||
Random rng = newRandom();
|
||||
Interval1D interval;
|
||||
int a,b,m;
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i){
|
||||
a = rng.nextInt(500);
|
||||
b = rng.nextInt(500);
|
||||
|
||||
if(a<=b){
|
||||
m = (b+a)/2;
|
||||
interval = new Interval1D(a,b);
|
||||
assertTrue(interval.contains(m));
|
||||
}
|
||||
}
|
||||
}
|
||||
@Test
|
||||
public void testContainsFails() {
|
||||
Random rng = newRandom();
|
||||
Interval1D interval;
|
||||
int a,b,c;
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i){
|
||||
a = rng.nextInt(500);
|
||||
b = rng.nextInt(500);
|
||||
c = rng.nextInt(500);
|
||||
if(a<=b && (c<a ||c>b)){
|
||||
interval = new Interval1D(a,b);
|
||||
assertFalse(interval.contains(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSizeOfIntersectionWith() {
|
||||
|
||||
Interval1D interval1;
|
||||
Interval1D interval2;
|
||||
int num[] = {
|
||||
1,1,0,2,1,
|
||||
1,2,1,5,2,
|
||||
1,4,0,2,2,
|
||||
1,4,0,1,1,
|
||||
2,4,0,1,0
|
||||
};
|
||||
for (int i = 0; i < num.length; i += 5) {
|
||||
interval1 = new Interval1D(num[i],num[i+1]);
|
||||
interval2 = new Interval1D(num[i+2],num[i+3]);
|
||||
assertEquals(interval1.sizeOfIntersectionWith(interval2), interval2.sizeOfIntersectionWith(interval1));
|
||||
assertEquals(interval1.sizeOfIntersectionWith(interval2), num[i+4], 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBoundingUnion() {
|
||||
Interval1D interval1;
|
||||
Interval1D interval2;
|
||||
Interval1D interval3;
|
||||
int num[] = {
|
||||
1,1,0,2,0,2,
|
||||
1,1,1,1,1,1,
|
||||
0,0,0,0,0,0,
|
||||
0,0,1,1,0,1,
|
||||
0,1,0,1,0,1,
|
||||
0,5,1,1,0,5,
|
||||
0,4,1,5,0,5,
|
||||
1,5,0,4,0,5,
|
||||
1,4,0,5,0,5,
|
||||
0,0,9,9,0,9
|
||||
};
|
||||
for (int i = 0; i < num.length; i += 6) {
|
||||
interval1 = new Interval1D(num[i],num[i+1]);
|
||||
interval2 = new Interval1D(num[i+2],num[i+3]);
|
||||
interval3 = new Interval1D(num[i+4],num[i+5]);
|
||||
assertTrue(interval1.boundingUnion(interval2).equals(interval3));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsUnionableWithTrue() {
|
||||
Interval1D interval1;
|
||||
Interval1D interval2;
|
||||
int num[] = {
|
||||
1,1,0,2,
|
||||
1,2,1,5,
|
||||
1,4,0,2,
|
||||
1,4,0,1,
|
||||
2,4,0,2,
|
||||
0,0,0,1,
|
||||
0,5,5,5,
|
||||
0,1,1,1,
|
||||
-1,1,0,2
|
||||
};
|
||||
for (int i = 0; i < num.length; i += 4) {
|
||||
interval1 = new Interval1D(num[i],num[i+1]);
|
||||
interval2 = new Interval1D(num[i+2],num[i+3]);
|
||||
assertEquals(interval1.isUnionableWith(interval2), interval2.isUnionableWith(interval1));
|
||||
assertTrue(interval1.isUnionableWith(interval2));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsUnionableWithFalse() {
|
||||
Interval1D interval1;
|
||||
Interval1D interval2;
|
||||
int num[] = {
|
||||
0,0,2,2,
|
||||
0,0,2,3,
|
||||
0,0,4,4,
|
||||
0,4,6,8,
|
||||
2,2,0,0,
|
||||
};
|
||||
for (int i = 0; i < num.length; i += 4) {
|
||||
interval1 = new Interval1D(num[i],num[i+1]);
|
||||
interval2 = new Interval1D(num[i+2],num[i+3]);
|
||||
assertEquals(interval1.isUnionableWith(interval2), interval2.isUnionableWith(interval1));
|
||||
assertFalse(interval1.isUnionableWith(interval2));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnion() {
|
||||
Interval1D interval1;
|
||||
Interval1D interval2;
|
||||
String str;
|
||||
int num[] = {
|
||||
1,1,0,2,0,2,
|
||||
1,1,1,1,1,1,
|
||||
0,0,0,0,0,0,
|
||||
0,1,0,1,0,1,
|
||||
0,1,0,1,0,1,
|
||||
0,5,1,1,0,5,
|
||||
0,4,1,5,0,5,
|
||||
1,5,0,4,0,5,
|
||||
1,4,0,5,0,5,
|
||||
};
|
||||
for (int i = 0; i < num.length; i += 6) {
|
||||
interval1 = new Interval1D(num[i],num[i+1]);
|
||||
interval2 = new Interval1D(num[i+2],num[i+3]);
|
||||
str =("["+num[i+4]+".."+num[i+5]+"]");
|
||||
assertEquals(str,interval1.union(interval2).toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testUnionFails() {
|
||||
|
||||
Interval1D interval1 = new Interval1D(0,0);
|
||||
Interval1D interval2 = new Interval1D(2,2);
|
||||
interval1.union(interval2);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualsObjectTrue() {
|
||||
Random rng = newRandom();
|
||||
Interval1D interval1;
|
||||
Interval1D interval2;
|
||||
int a,b;
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i){
|
||||
a = rng.nextInt(500);
|
||||
b = rng.nextInt(500);
|
||||
|
||||
if(a<=b){
|
||||
interval1 = new Interval1D(a,b);
|
||||
interval2 = new Interval1D(a,b);
|
||||
assertTrue(interval1.equals(interval2));
|
||||
assertEquals(interval1.equals(interval2), interval2.equals(interval1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualsObjectFalse() {
|
||||
Random rng = newRandom();
|
||||
Interval1D interval1;
|
||||
String str = "";
|
||||
int a,b;
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i){
|
||||
a = rng.nextInt(500);
|
||||
b = rng.nextInt(500);
|
||||
if(a<=b){
|
||||
interval1 = new Interval1D(a,b);
|
||||
assertFalse(interval1.equals(str));
|
||||
assertEquals(interval1.equals(str), str.equals(interval1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
Random rng = newRandom();
|
||||
Interval1D interval1;
|
||||
int a,b;
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i){
|
||||
a = rng.nextInt(500);
|
||||
b = rng.nextInt(500);
|
||||
if(a<=b){
|
||||
interval1 = new Interval1D(a,b);
|
||||
assertEquals(interval1.toString(),"["+a+".."+b+"]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
161
Alpano/tests/ch/epfl/alpano/Interval1DTestP.java
Normal file
@@ -0,0 +1,161 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
import static ch.epfl.test.ObjectTest.hashCodeIsCompatibleWithEquals;
|
||||
import static ch.epfl.test.TestRandomizer.RANDOM_ITERATIONS;
|
||||
import static ch.epfl.test.TestRandomizer.newRandom;
|
||||
import static java.lang.Math.ceil;
|
||||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
import static java.lang.Math.sqrt;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class Interval1DTestP {
|
||||
private static Interval1D i_0_9() { return new Interval1D(0, 9); }
|
||||
private static Interval1D i_0_2() { return new Interval1D(0, 2); }
|
||||
private static Interval1D i_3_5() { return new Interval1D(3, 5); }
|
||||
private static Interval1D i_4_6() { return new Interval1D(4, 6); }
|
||||
private static Interval1D i_6_9() { return new Interval1D(6, 9); }
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorFailsForInvalidBounds() {
|
||||
new Interval1D(1, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWorksForSingletonInterval() {
|
||||
new Interval1D(10, 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsIsTrueOnlyForTheIntervalsElements() {
|
||||
int sqrtIt = (int)ceil(sqrt(RANDOM_ITERATIONS));
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < sqrtIt; ++i) {
|
||||
int a = rng.nextInt(200) - 100;
|
||||
int b = a + rng.nextInt(50);
|
||||
Interval1D interval = new Interval1D(a, b);
|
||||
for (int j = 0; j < sqrtIt; ++j) {
|
||||
int v = rng.nextInt(200) - 100;
|
||||
assertEquals(a <= v && v <= b, interval.contains(v));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsWorksAtTheLimit() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
int max = rng.nextInt(2000);
|
||||
int a = rng.nextInt(max) - 1000;
|
||||
int b = max - 1000;
|
||||
Interval1D interval = new Interval1D(a, b);
|
||||
assertFalse(interval.contains(a - 1));
|
||||
assertTrue(interval.contains(a));
|
||||
assertTrue(interval.contains(b));
|
||||
assertFalse(interval.contains(b + 1));
|
||||
}
|
||||
}
|
||||
@Test
|
||||
public void sizeWorksOnKnownIntervals() {
|
||||
assertEquals(10, i_0_9().size());
|
||||
assertEquals(3, i_0_2().size());
|
||||
assertEquals(3, i_3_5().size());
|
||||
assertEquals(3, i_4_6().size());
|
||||
assertEquals(4, i_6_9().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sizeOfIntersectionWorksOnNonIntersectingIntervals() {
|
||||
assertEquals(0, i_0_2().sizeOfIntersectionWith(i_3_5()));
|
||||
assertEquals(0, i_0_2().sizeOfIntersectionWith(i_4_6()));
|
||||
assertEquals(0, i_0_2().sizeOfIntersectionWith(i_6_9()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sizeOfIntersectionWorksOnIntersectingIntervals() {
|
||||
assertEquals(3, i_0_2().sizeOfIntersectionWith(i_0_9()));
|
||||
assertEquals(3, i_0_9().sizeOfIntersectionWith(i_0_2()));
|
||||
assertEquals(1, i_4_6().sizeOfIntersectionWith(i_6_9()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void boundingUnionWorksOnKnownIntervals() {
|
||||
assertEquals(0, i_0_2().boundingUnion(i_6_9()).includedFrom());
|
||||
assertEquals(9, i_0_2().boundingUnion(i_6_9()).includedTo());
|
||||
assertEquals(0, i_6_9().boundingUnion(i_0_2()).includedFrom());
|
||||
assertEquals(9, i_6_9().boundingUnion(i_0_2()).includedTo());
|
||||
assertEquals(0, i_0_9().boundingUnion(i_0_9()).includedFrom());
|
||||
assertEquals(9, i_0_9().boundingUnion(i_0_9()).includedTo());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isUnionableWithWorksOnKnownIntervals() {
|
||||
// Intersecting intervals
|
||||
assertTrue(i_0_9().isUnionableWith(i_0_9()));
|
||||
assertTrue(i_0_9().isUnionableWith(i_3_5()));
|
||||
assertTrue(i_3_5().isUnionableWith(i_3_5()));
|
||||
assertTrue(i_3_5().isUnionableWith(i_0_9()));
|
||||
assertTrue(i_3_5().isUnionableWith(i_4_6()));
|
||||
assertTrue(i_4_6().isUnionableWith(i_4_6()));
|
||||
assertTrue(i_4_6().isUnionableWith(i_3_5()));
|
||||
|
||||
// Contiguous intervals
|
||||
assertTrue(i_3_5().isUnionableWith(i_6_9()));
|
||||
assertTrue(i_6_9().isUnionableWith(i_3_5()));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void unionFailsOnNonUnionableIntervals() {
|
||||
i_0_2().union(i_6_9());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unionWorksWhenOneIntervalContainsTheOther() {
|
||||
assertEquals(i_0_9(), i_0_9().union(i_3_5()));
|
||||
assertEquals(i_0_9(), i_3_5().union(i_0_9()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unionWorksWithASingleInterval() {
|
||||
assertEquals(i_3_5(), i_3_5().union(i_3_5()).union(i_3_5()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unionWorksWhenOneIntervalIsContiguousWithTheOther() {
|
||||
Interval1D i = i_0_2().union(i_6_9().union(i_3_5()));
|
||||
assertEquals(i_0_9(), i);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalsIsStructural() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
int a = rng.nextInt(), b = rng.nextInt();
|
||||
Interval1D int1 = new Interval1D(min(a, b), max(a, b));
|
||||
Interval1D int2 = new Interval1D(min(a, b), max(a, b));
|
||||
Interval1D int3 = new Interval1D(min(a, b) + 1, max(a, b) + 1);
|
||||
assertTrue(int1.equals(int2));
|
||||
assertFalse(int1.equals(int3));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hashCodeAndEqualsAreCompatible() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
int a = rng.nextInt(), b = rng.nextInt();
|
||||
int c = rng.nextInt(), d = rng.nextInt();
|
||||
Interval1D int1 = new Interval1D(min(a, b), max(a, b));
|
||||
Interval1D int2 = new Interval1D(min(c, d), max(c, d));
|
||||
Interval1D int3 = new Interval1D(min(c, d), max(c, d));
|
||||
assertTrue(hashCodeIsCompatibleWithEquals(int1, int2));
|
||||
assertTrue(hashCodeIsCompatibleWithEquals(int2, int3));
|
||||
}
|
||||
}
|
||||
}
|
227
Alpano/tests/ch/epfl/alpano/Interval2DTest.java
Normal file
@@ -0,0 +1,227 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.util.HashMap;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
public class Interval2DTest {
|
||||
|
||||
@Test(expected= NullPointerException.class)
|
||||
public void testInterval2D() {
|
||||
new Interval2D(null, null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testContains() {
|
||||
|
||||
HashMap<int[][], int[]> testValues = new HashMap<int[][], int[]>();
|
||||
|
||||
testValues.put(new int[][] { {0,4}, {0,4} }, new int[] {2,4});
|
||||
testValues.put(new int[][] { {0,0}, {0,0} }, new int[] {0,0});
|
||||
|
||||
|
||||
for (int[][] values : testValues.keySet()){
|
||||
|
||||
assertEquals ( true ,
|
||||
|
||||
new Interval2D(
|
||||
new Interval1D(values[0][0], values[0][1]),
|
||||
new Interval1D(values[1][0], values[1][1])).contains(testValues.get(values)[0],
|
||||
testValues.get(values)[1])
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
testValues = new HashMap<int[][], int[]>();
|
||||
|
||||
testValues.put(new int[][] { {0,4}, {0,4} }, new int[] {-1,-1});
|
||||
testValues.put(new int[][] { {0,0}, {0,0} }, new int[] {0,1});
|
||||
|
||||
|
||||
for (int[][] values : testValues.keySet()){
|
||||
|
||||
assertEquals ( false,
|
||||
|
||||
new Interval2D(
|
||||
new Interval1D(values[0][0], values[0][1]),
|
||||
new Interval1D(values[1][0], values[1][1])).contains(testValues.get(values)[0],
|
||||
testValues.get(values)[1])
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSize() {
|
||||
HashMap<int[][], Integer> testValues = new HashMap<int[][], Integer>();
|
||||
|
||||
testValues.put(new int[][] { {0,4}, {0,4} }, 25);
|
||||
testValues.put(new int[][] { {0,0}, {0,0} }, 1);
|
||||
|
||||
|
||||
for (int[][] values : testValues.keySet()){
|
||||
|
||||
assertEquals ( (int)testValues.get(values),
|
||||
|
||||
new Interval2D(
|
||||
new Interval1D(values[0][0], values[0][1]),
|
||||
new Interval1D(values[1][0], values[1][1])).size()
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSizeOfIntersectionWith() {
|
||||
HashMap<int[][][], Integer> testValues = new HashMap<int[][][], Integer>();
|
||||
|
||||
|
||||
|
||||
testValues.put( new int[][][] { {{0,5}, {0,5}} , {{4,6},{4,6}} } , 4);
|
||||
testValues.put( new int[][][] { {{0,0}, {0,0}} , {{-40,40},{-40,40}} } , 1);
|
||||
testValues.put( new int[][][] { {{0,5}, {0,5}} , {{10,15},{10,15}} } , 0);
|
||||
|
||||
for (int[][][] values : testValues.keySet()){
|
||||
|
||||
assertEquals ( (int)testValues.get(values),
|
||||
|
||||
new Interval2D(
|
||||
new Interval1D(values[0][0][0], values[0][0][1]),
|
||||
new Interval1D(values[0][1][0], values[0][1][1])).sizeOfIntersectionWith(
|
||||
new Interval2D(
|
||||
new Interval1D(values[1][0][0], values[1][0][1]),
|
||||
new Interval1D(values[1][1][0], values[1][1][1])))
|
||||
);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBoundingUnion() {
|
||||
HashMap<int[][][], int[][]> testValues = new HashMap<int[][][], int[][]>();
|
||||
|
||||
|
||||
testValues.put( new int[][][] {{{0,5}, {0,5}} , {{4,6},{4,6}} } , new int[][] {{0,6},{0,6}} );
|
||||
testValues.put( new int[][][] {{{0,0}, {0,0}} , {{4,6},{4,6}} } , new int[][] {{0,6},{0,6}} );
|
||||
|
||||
for (int[][][] values : testValues.keySet()){
|
||||
|
||||
assertEquals (true,
|
||||
new Interval2D(
|
||||
new Interval1D(values[0][0][0], values[0][0][1]),
|
||||
new Interval1D(values[0][1][0], values[0][1][1])).boundingUnion(
|
||||
new Interval2D(
|
||||
new Interval1D(values[1][0][0], values[1][0][1]),
|
||||
new Interval1D(values[1][1][0], values[1][1][1]))).equals(
|
||||
new Interval2D(
|
||||
new Interval1D(testValues.get(values)[0][0], testValues.get(values)[0][1]),
|
||||
new Interval1D(testValues.get(values)[1][0], testValues.get(values)[1][1]))
|
||||
));
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsUnionableWith() {
|
||||
HashMap<int[][][], Boolean> testValues = new HashMap<int[][][], Boolean>();
|
||||
|
||||
testValues.put( new int[][][] {{{0,5}, {0,5}} , {{4,6},{4,6}} } ,false);
|
||||
testValues.put( new int[][][] {{{0,0}, {0,0}} , {{1,6},{1,6}} } , false );
|
||||
|
||||
for (int[][][] values : testValues.keySet()){
|
||||
|
||||
assertEquals ( true,
|
||||
testValues.get(values) == new Interval2D(
|
||||
new Interval1D(values[0][0][0], values[0][0][1]),
|
||||
new Interval1D(values[0][1][0], values[0][1][1])).isUnionableWith(
|
||||
new Interval2D(
|
||||
new Interval1D(values[1][0][0], values[1][0][1]),
|
||||
new Interval1D(values[1][1][0], values[1][1][1]))));
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testUnion() {
|
||||
HashMap<int[][][], int[][]> testValues = new HashMap<int[][][], int[][]>();
|
||||
|
||||
|
||||
testValues.put( new int[][][] {{{0,5}, {0,5}} , {{4,6},{4,6}} } , new int[][] {{4,5},{4,5}} );
|
||||
testValues.put( new int[][][] {{{-100,-100}, {0,0}} , {{0,0},{100,100}} } , new int[][] {{0,0},{0,0}} );
|
||||
testValues.put( new int[][][] {{{-100,100}, {0,0}} , {{0,0},{-100,100}} } , new int[][] {{0,0},{0,0}} );
|
||||
|
||||
for (int[][][] values : testValues.keySet()){
|
||||
|
||||
assertEquals (false,
|
||||
new Interval2D(
|
||||
new Interval1D(values[0][0][0], values[0][0][1]),
|
||||
new Interval1D(values[0][1][0], values[0][1][1])).union(
|
||||
new Interval2D(
|
||||
new Interval1D(values[1][0][0], values[1][0][1]),
|
||||
new Interval1D(values[1][1][0], values[1][1][1]))).equals(
|
||||
new Interval2D(
|
||||
new Interval1D(testValues.get(values)[0][0], testValues.get(values)[0][1]),
|
||||
new Interval1D(testValues.get(values)[1][0], testValues.get(values)[1][1]))
|
||||
));
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
new Interval2D(
|
||||
new Interval1D(0, 0),
|
||||
new Interval1D(0, 0)).union(
|
||||
new Interval2D(
|
||||
new Interval1D(1, 1),
|
||||
new Interval1D(1, 1)));
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualsObject() {
|
||||
HashMap<int[][][], Boolean> testValues = new HashMap<int[][][], Boolean>();
|
||||
|
||||
testValues.put( new int[][][] {{{0,5}, {0,5}} , {{0,5},{0,5}} } ,true );
|
||||
testValues.put( new int[][][] {{{0,5}, {0,5}} , {{0,5},{0,6}} } , false );
|
||||
|
||||
for (int[][][] values : testValues.keySet()){
|
||||
|
||||
assertEquals ( testValues.get(values) , new Interval2D(
|
||||
new Interval1D(values[0][0][0], values[0][0][1]),
|
||||
new Interval1D(values[0][1][0], values[0][1][1])).equals(
|
||||
new Interval2D(
|
||||
new Interval1D(values[1][0][0], values[1][0][1]),
|
||||
new Interval1D(values[1][1][0], values[1][1][1]))) );
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
HashMap<int[][], String> testValues = new HashMap<int[][], String>();
|
||||
|
||||
testValues.put(new int[][] { {0,4}, {0,4} }, "[0..4]x[0..4]");
|
||||
|
||||
|
||||
for (int[][] values : testValues.keySet()){
|
||||
|
||||
assertEquals (testValues.get(values),
|
||||
|
||||
new Interval2D(
|
||||
new Interval1D(values[0][0], values[0][1]),
|
||||
new Interval1D(values[1][0], values[1][1])).toString()
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
209
Alpano/tests/ch/epfl/alpano/Interval2DTestP.java
Normal file
@@ -0,0 +1,209 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
import static ch.epfl.test.ObjectTest.hashCodeIsCompatibleWithEquals;
|
||||
import static ch.epfl.test.TestRandomizer.RANDOM_ITERATIONS;
|
||||
import static ch.epfl.test.TestRandomizer.newRandom;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class Interval2DTestP {
|
||||
private static Interval2D newInterval2D(int x1, int x2, int y1, int y2) {
|
||||
return new Interval2D(new Interval1D(x1, x2), new Interval1D(y1, y2));
|
||||
}
|
||||
|
||||
private static Interval2D i_0_10_0_10() {
|
||||
return newInterval2D(0, 10, 0, 10);
|
||||
}
|
||||
|
||||
private static Interval2D i_0_9_0_11() {
|
||||
return newInterval2D(0, 9, 0, 11);
|
||||
}
|
||||
|
||||
private static Interval2D i_0_10_11_20() {
|
||||
return newInterval2D(0, 10, 11, 20);
|
||||
}
|
||||
|
||||
private static Interval2D i_0_10_0_20() {
|
||||
return newInterval2D(0, 10, 0, 20);
|
||||
}
|
||||
|
||||
private static Interval2D i_11_20_0_10() {
|
||||
return newInterval2D(11, 20, 0, 10);
|
||||
}
|
||||
|
||||
private static Interval2D i_0_20_0_10() {
|
||||
return newInterval2D(0, 20, 0, 10);
|
||||
}
|
||||
|
||||
private static Interval2D i_2_2_2_2() {
|
||||
return newInterval2D(2, 2, 2, 2);
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void constructorFailsOnInvalidInterval() {
|
||||
new Interval2D(null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsWorksOnKnownIntervals() {
|
||||
Interval2D i = i_2_2_2_2();
|
||||
for (int x = 1; x <= 3; ++x) {
|
||||
for (int y = 1; y <= 3; ++y) {
|
||||
assertEquals(x == 2 && y == 2, i.contains(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sizeWorksOnKnownIntervals() {
|
||||
assertEquals(1, i_2_2_2_2().size());
|
||||
assertEquals(21 * 11, i_0_20_0_10().size());
|
||||
assertEquals(10 * 11, i_11_20_0_10().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sizeOfIntersectionWorksOnNonIntersectingIntervals() {
|
||||
assertEquals(0, i_2_2_2_2().sizeOfIntersectionWith(i_11_20_0_10()));
|
||||
assertEquals(0, i_11_20_0_10().sizeOfIntersectionWith(i_2_2_2_2()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sizeOfIntersectionWorksOnIntersectingIntervals() {
|
||||
assertEquals(1, i_2_2_2_2().sizeOfIntersectionWith(i_2_2_2_2()));
|
||||
assertEquals(21 * 11, i_0_20_0_10().sizeOfIntersectionWith(i_0_20_0_10()));
|
||||
assertEquals(1, i_2_2_2_2().sizeOfIntersectionWith(i_0_20_0_10()));
|
||||
assertEquals(1, i_0_20_0_10().sizeOfIntersectionWith(i_2_2_2_2()));
|
||||
assertEquals(10 * 11, i_0_10_0_10().sizeOfIntersectionWith(i_0_9_0_11()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void boudingUnionWorksOnKnownIntervals() {
|
||||
assertEquals(i_2_2_2_2(), i_2_2_2_2().boundingUnion(i_2_2_2_2()));
|
||||
|
||||
Interval2D i1 = i_0_10_0_10().boundingUnion(i_0_9_0_11());
|
||||
assertEquals(0, i1.iX().includedFrom());
|
||||
assertEquals(10, i1.iX().includedTo());
|
||||
assertEquals(0, i1.iY().includedFrom());
|
||||
assertEquals(11, i1.iY().includedTo());
|
||||
|
||||
Interval2D i2 = i_2_2_2_2().boundingUnion(i_11_20_0_10());
|
||||
assertEquals(2, i2.iX().includedFrom());
|
||||
assertEquals(20, i2.iX().includedTo());
|
||||
assertEquals(0, i2.iY().includedFrom());
|
||||
assertEquals(10, i2.iY().includedTo());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isUnionableWorksOnKnownUnionableIntervals() {
|
||||
assertTrue(i_0_10_0_10().isUnionableWith(i_0_10_0_10()));
|
||||
assertTrue(i_0_10_0_10().isUnionableWith(i_0_10_11_20()));
|
||||
assertTrue(i_0_10_11_20().isUnionableWith(i_0_10_0_10()));
|
||||
assertTrue(i_0_10_0_10().isUnionableWith(i_11_20_0_10()));
|
||||
assertTrue(i_11_20_0_10().isUnionableWith(i_0_10_0_10()));
|
||||
assertTrue(i_0_10_0_10().isUnionableWith(i_2_2_2_2()));
|
||||
assertTrue(i_2_2_2_2().isUnionableWith(i_0_10_0_10()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isUnionableWorksOnKnownNonUnionableIntervals() {
|
||||
assertFalse(i_2_2_2_2().isUnionableWith(i_11_20_0_10()));
|
||||
assertFalse(i_11_20_0_10().isUnionableWith(i_2_2_2_2()));
|
||||
assertFalse(i_0_9_0_11().isUnionableWith(i_0_10_0_10()));
|
||||
assertFalse(i_0_10_0_10().isUnionableWith(i_0_9_0_11()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isUnionableWithIsReflexive() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
Interval2D interval = nextInterval(rng, 500, 1000);
|
||||
assertTrue(interval.isUnionableWith(interval));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isUnionableWithIsSymmetric() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
Interval2D i1 = nextInterval(rng, 5, 10);
|
||||
Interval2D i2 = nextInterval(rng, 5, 10);
|
||||
assertTrue(! i1.isUnionableWith(i2) || i2.isUnionableWith(i1));
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void unionFailsOnNonUnionableIntervals() {
|
||||
i_2_2_2_2().union(i_11_20_0_10());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unionWorksOnASingleInterval() {
|
||||
assertEquals(i_0_10_0_10(), i_0_10_0_10().union(i_0_10_0_10().union(i_0_10_0_10())));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unionWorksOnKnownIntervals() {
|
||||
assertEquals(i_0_10_0_10(), i_0_10_0_10().union(i_2_2_2_2()));
|
||||
assertEquals(i_0_10_0_10(), i_2_2_2_2().union(i_0_10_0_10()));
|
||||
|
||||
assertEquals(i_0_10_0_20(), i_0_10_0_10().union(i_0_10_11_20()));
|
||||
assertEquals(i_0_10_0_20(), i_0_10_11_20().union(i_0_10_0_10()));
|
||||
|
||||
assertEquals(i_0_20_0_10(), i_0_10_0_10().union(i_11_20_0_10()));
|
||||
assertEquals(i_0_20_0_10(), i_11_20_0_10().union(i_0_10_0_10()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unionIsCommutative() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
Interval2D i1 = nextInterval(rng, 5, 10);
|
||||
Interval2D i2 = nextInterval(rng, 5, 10);
|
||||
if (i1.isUnionableWith(i2))
|
||||
assertEquals(i1.union(i2), i2.union(i1));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalsIsStructural() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
int x1 = rng.nextInt(1000) - 500;
|
||||
int x2 = x1 + rng.nextInt(1000);
|
||||
int y1 = rng.nextInt(1000) - 500;
|
||||
int y2 = y1 + rng.nextInt(1000);
|
||||
Interval2D int1 = newInterval2D(x1, x2, y1, y2);
|
||||
Interval2D int2 = newInterval2D(x1, x2, y1, y2);
|
||||
Interval2D int3 = newInterval2D(x1, x2, y1, y2 + 1);
|
||||
assertTrue(int1.equals(int2));
|
||||
assertTrue(int2.equals(int1));
|
||||
assertFalse(int1.equals(int3));
|
||||
assertFalse(int3.equals(int1));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hashCodeAndEqualsAreCompatible() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
int a = rng.nextInt(1000) - 500, b = a + rng.nextInt(20);
|
||||
int c = rng.nextInt(1000) - 500, d = c + rng.nextInt(20);
|
||||
Interval2D i1 = newInterval2D(a, b, c, d);
|
||||
Interval2D i1b = newInterval2D(a, b, c, d);
|
||||
Interval2D i2 = newInterval2D(a, b, c, d + 1);
|
||||
assertTrue(hashCodeIsCompatibleWithEquals(i1, i1b));
|
||||
assertTrue(hashCodeIsCompatibleWithEquals(i1, i2));
|
||||
}
|
||||
}
|
||||
|
||||
private Interval2D nextInterval(Random rng, int maxOffset, int maxSize) {
|
||||
int offsetX = rng.nextInt(maxOffset), offsetY = rng.nextInt(maxOffset);
|
||||
int sizeX = rng.nextInt(maxSize), sizeY = rng.nextInt(maxSize);
|
||||
return newInterval2D(-offsetX, sizeX - offsetX, -offsetY, sizeY - offsetY);
|
||||
}
|
||||
}
|
217
Alpano/tests/ch/epfl/alpano/Math2Test.java
Normal file
@@ -0,0 +1,217 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
import static ch.epfl.alpano.Math2.angularDistance;
|
||||
import static ch.epfl.alpano.Math2.bilerp;
|
||||
import static ch.epfl.alpano.Math2.firstIntervalContainingRoot;
|
||||
import static ch.epfl.alpano.Math2.floorMod;
|
||||
import static ch.epfl.alpano.Math2.haversin;
|
||||
import static ch.epfl.alpano.Math2.improveRoot;
|
||||
import static ch.epfl.alpano.Math2.lerp;
|
||||
import static ch.epfl.alpano.Math2.sq;
|
||||
import static ch.epfl.test.TestRandomizer.RANDOM_ITERATIONS;
|
||||
import static ch.epfl.test.TestRandomizer.newRandom;
|
||||
import static java.lang.Math.PI;
|
||||
import static java.lang.Math.cos;
|
||||
import static java.lang.Math.floor;
|
||||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
import static java.lang.Math.sin;
|
||||
import static java.lang.Math.toRadians;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.function.DoubleUnaryOperator;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class Math2Test {
|
||||
@Test
|
||||
public void sqSquaresRandomValues() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double x = rng.nextDouble() * 1_000d - 500d;
|
||||
assertEquals(x * x, sq(x), 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void floorModWorksOnRandomValues() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double n = rng.nextDouble() * 1_000d - 500d;
|
||||
double d = 0;
|
||||
while (d == 0)
|
||||
d = rng.nextDouble() * 1_000d - 500d;
|
||||
double q = (int)floor(n / d);
|
||||
double r = floorMod(n, d);
|
||||
assertEquals(n, q * d + r, 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void haversinWorksOnRandomAngles() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double a = nextAngle(rng);
|
||||
double h = (1d - cos(a)) / 2d;
|
||||
assertEquals(h, haversin(a), 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void angularDistanceWorksOnKnownAngles() {
|
||||
double data[] = {
|
||||
0, 45, 45,
|
||||
45, 0, -45,
|
||||
0, 179, 179,
|
||||
0, 181, -179,
|
||||
181, 359, 178,
|
||||
181, 2, -179
|
||||
};
|
||||
for (int i = 0; i < data.length; i += 3) {
|
||||
double a1 = toRadians(data[i]);
|
||||
double a2 = toRadians(data[i + 1]);
|
||||
double expectedD = toRadians(data[i + 2]);
|
||||
assertEquals(expectedD, angularDistance(a1, a2), 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void angularDistanceIsInExpectedRange() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double a1 = nextAngle(rng);
|
||||
double a2 = nextAngle(rng);
|
||||
double d = angularDistance(a1, a2);
|
||||
assertTrue(-PI <= d && d < PI);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void angularDistanceIsSymmetric() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double a1 = nextAngle(rng);
|
||||
double a2 = nextAngle(rng);
|
||||
assertEquals(0, angularDistance(a1, a2) + angularDistance(a2, a1), 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lerpIsFirstValueAtStart() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double v1 = (rng.nextDouble() - 0.5) * 1000d;
|
||||
double v2 = (rng.nextDouble() - 0.5) * 1000d;
|
||||
assertEquals(v1, lerp(v1, v2, 0), 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lerpIsAverageValueAtMiddle() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double v1 = (rng.nextDouble() - 0.5) * 1000d;
|
||||
double v2 = (rng.nextDouble() - 0.5) * 1000d;
|
||||
assertEquals((v1 + v2) / 2d, lerp(v1, v2, 0.5), 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lerpIsSecondValueAtEnd() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double v1 = (rng.nextDouble() - 0.5) * 1000d;
|
||||
double v2 = (rng.nextDouble() - 0.5) * 1000d;
|
||||
assertEquals(v2, lerp(v1, v2, 1), 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lerpIsInExpectedRange() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double v1 = (rng.nextDouble() - 0.5) * 1000d;
|
||||
double v2 = (rng.nextDouble() - 0.5) * 1000d;
|
||||
double p = rng.nextDouble();
|
||||
double v = lerp(v1, v2, p);
|
||||
assertTrue(min(v1, v2) <= v && v <= max(v1, v2));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bilerpIsInExpectedRange() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double v1 = (rng.nextDouble() - 0.5) * 1000d;
|
||||
double v2 = (rng.nextDouble() - 0.5) * 1000d;
|
||||
double v3 = (rng.nextDouble() - 0.5) * 1000d;
|
||||
double v4 = (rng.nextDouble() - 0.5) * 1000d;
|
||||
double x = rng.nextDouble(), y = rng.nextDouble();
|
||||
double v = bilerp(v1, v2, v3, v4, x, y);
|
||||
assertTrue(min(min(v1, v2), min(v3, v4)) <= v
|
||||
&& v <= max(max(v1, v2), max(v3, v4)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bilerpIsCorrectInCorners() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double v0 = rng.nextDouble(), v1 = rng.nextDouble();
|
||||
double v2 = rng.nextDouble(), v3 = rng.nextDouble();
|
||||
assertEquals(v0, bilerp(v0, v1, v2, v3, 0, 0), 1e-10);
|
||||
assertEquals(v1, bilerp(v1, v1, v2, v3, 1, 0), 1e-10);
|
||||
assertEquals(v2, bilerp(v2, v1, v2, v3, 0, 1), 1e-10);
|
||||
assertEquals(v3, bilerp(v3, v1, v2, v3, 1, 1), 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bilerpLerpsAlongSides() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double v0 = rng.nextDouble(), v1 = rng.nextDouble();
|
||||
double v2 = rng.nextDouble(), v3 = rng.nextDouble();
|
||||
assertEquals((v0 + v1)/2d, bilerp(v0, v1, v2, v3, 0.5, 0), 1e-10);
|
||||
assertEquals((v0 + v2)/2d, bilerp(v0, v1, v2, v3, 0, 0.5), 1e-10);
|
||||
assertEquals((v2 + v3)/2d, bilerp(v0, v1, v2, v3, 0.5, 1), 1e-10);
|
||||
assertEquals((v1 + v3)/2d, bilerp(v0, v1, v2, v3, 1, 0.5), 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void firstIntervalContainingRootWorksOnSin() {
|
||||
double i1 = firstIntervalContainingRoot(new Sin(), -1d, 1d, 0.1 + 1e-11);
|
||||
assertEquals(-0.1, i1, 1e-10);
|
||||
|
||||
double i2 = firstIntervalContainingRoot(new Sin(), 1, 4, 1);
|
||||
assertEquals(3, i2, 0);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void improveRootFailsWhenIntervalDoesNotContainRoot() {
|
||||
improveRoot(new Sin(), 1, 2, 1e-10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void improveRootWorksOnSin() {
|
||||
double pi = improveRoot(new Sin(), 3.1, 3.2, 1e-10);
|
||||
assertEquals(PI, pi, 1e-10);
|
||||
|
||||
double mPi = improveRoot(new Sin(), -4, -3.1, 1e-10);
|
||||
assertEquals(-PI, mPi, 1e-10);
|
||||
}
|
||||
|
||||
private static double nextAngle(Random rng) {
|
||||
return rng.nextDouble() * 2d * PI;
|
||||
}
|
||||
}
|
||||
|
||||
class Sin implements DoubleUnaryOperator {
|
||||
@Override
|
||||
public double applyAsDouble(double x) {
|
||||
return sin(x);
|
||||
}
|
||||
}
|
45
Alpano/tests/ch/epfl/alpano/PanoramaCompTest.java
Normal file
@@ -0,0 +1,45 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ch.epfl.alpano.dem.ContinuousElevationModel;
|
||||
import ch.epfl.alpano.dem.ElevationProfile;
|
||||
|
||||
public class PanoramaCompTest {
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void throwsNullPointerUponConstruction(){
|
||||
new PanoramaComputer(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givesTrivialZero(){
|
||||
|
||||
|
||||
double zero =PanoramaComputer.rayToGroundDistance(
|
||||
|
||||
new ElevationProfile( new ContinuousElevationModel(new TestDemForPanoramaComp(new Interval2D(new Interval1D(-100, 100),
|
||||
new Interval1D(-100, 100)))),
|
||||
new GeoPoint(0,0),2.5,100), 0.0, 0.0).applyAsDouble(
|
||||
1);
|
||||
|
||||
assertEquals(0, zero,0.01);
|
||||
|
||||
|
||||
}
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void throwsIllegalArgumentExceptionOnNegValues(){
|
||||
double zero =PanoramaComputer.rayToGroundDistance(
|
||||
|
||||
new ElevationProfile( new ContinuousElevationModel(new TestDemForPanoramaComp(new Interval2D(new Interval1D(-100, 100),
|
||||
new Interval1D(-100, 100)))),
|
||||
new GeoPoint(0,0),0,100), 0.0, 1.0).applyAsDouble(
|
||||
-50);
|
||||
|
||||
assertEquals(0, zero,0);
|
||||
}
|
||||
|
||||
|
||||
}
|
1135
Alpano/tests/ch/epfl/alpano/PanoramaComputerTestP.java
Normal file
95
Alpano/tests/ch/epfl/alpano/PanoramaParametersTest.java
Normal file
@@ -0,0 +1,95 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PanoramaParametersTest {
|
||||
|
||||
private GeoPoint vp = new GeoPoint(Math.toRadians(6.8087),Math.toRadians(47.0085));
|
||||
private PanoramaParameters pp = new PanoramaParameters(vp, 1380, Math.toRadians(162),
|
||||
Math.toRadians(27), 300, 2500, 800);
|
||||
|
||||
|
||||
@Test
|
||||
public void testAzimuthForX() {
|
||||
assertEquals(pp.azimuthForX(1),Math.toRadians(148.5108043217287),0.000001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXForAzimuth() {
|
||||
assertEquals(pp.xForAzimuth(pp.azimuthForX(1)),1,0.000000001);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testXForAzimuthFails() {
|
||||
pp.xForAzimuth(Math.toRadians(27-81.5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAltitudeForY() {
|
||||
assertEquals(pp.altitudeForY(0),Math.toRadians(4.316326530612245),0.00000001);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testYForAltitude() {
|
||||
assertEquals(pp.yForAltitude(pp.altitudeForY(1)),1,0.000000001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsValidSampleIndexFails1() {
|
||||
assertEquals(pp.isValidSampleIndex(2500, 800),false);
|
||||
}
|
||||
@Test
|
||||
public void testIsValidSampleIndexFails2() {
|
||||
assertEquals(pp.isValidSampleIndex(-1, -1),false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLinearSampleIndexSucces() {
|
||||
assertEquals(pp.linearSampleIndex(0, 0),0);
|
||||
assertEquals(pp.linearSampleIndex(2500-1, 800-1),(2500*800)-1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObserverPosition() {
|
||||
assertEquals(pp.observerPosition(),vp);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObserverElevation() {
|
||||
assertEquals(pp.observerElevation(),1380,0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCenterAzimuth() {
|
||||
assertEquals(pp.centerAzimuth(),Math.toRadians(162),0.00000001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHorizontalFieldOfView() {
|
||||
assertEquals(pp.horizontalFieldOfView(),Math.toRadians(27),0.0000001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVerticalFieldOfView() {
|
||||
assertEquals(pp.verticalFieldOfView(),Math.toRadians(8.63265306122),0.000000001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxDistance() {
|
||||
assertEquals(pp.maxDistance(),300,0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWidth() {
|
||||
assertEquals(pp.width(),2500,0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHeight() {
|
||||
assertEquals(pp.height(),800,0);
|
||||
}
|
||||
|
||||
}
|
167
Alpano/tests/ch/epfl/alpano/PanoramaParametersTestP.java
Normal file
@@ -0,0 +1,167 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
import static ch.epfl.test.TestRandomizer.RANDOM_ITERATIONS;
|
||||
import static ch.epfl.test.TestRandomizer.newRandom;
|
||||
import static java.lang.Math.PI;
|
||||
import static java.lang.Math.floorMod;
|
||||
import static java.lang.Math.nextUp;
|
||||
import static java.lang.Math.toRadians;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PanoramaParametersTestP {
|
||||
// Default (and valid) arguments for constructor
|
||||
private static GeoPoint O_POS() { return new GeoPoint(toRadians(4), toRadians(4)); }
|
||||
private static int O_EL = 1000;
|
||||
private static double C_AZ = toRadians(180);
|
||||
private static double H_FOV = toRadians(60);
|
||||
private static int MAX_D = 1000;
|
||||
private static int W = 100, H = 100;
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void constructorFailsWithNullObserverPosition() {
|
||||
new PanoramaParameters(null, O_EL, C_AZ, H_FOV, MAX_D, W, H);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorFailsWithNonCanonicalAzimuth() {
|
||||
new PanoramaParameters(O_POS(), O_EL, 42d, H_FOV, MAX_D, W, H);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorFailsWithZeroFieldOfView() {
|
||||
new PanoramaParameters(O_POS(), O_EL, C_AZ, 0, MAX_D, W, H);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorFailsWithTooLargeOfView() {
|
||||
new PanoramaParameters(O_POS(), O_EL, C_AZ, nextUp(2d * PI), MAX_D, W, H);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorFailsWithZeroWidth() {
|
||||
new PanoramaParameters(O_POS(), O_EL, C_AZ, H_FOV, MAX_D, 0, H);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorFailsWithZeroHeight() {
|
||||
new PanoramaParameters(O_POS(), O_EL, C_AZ, H_FOV, MAX_D, W, 0);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorFailsWithZeroMaxDistance() {
|
||||
new PanoramaParameters(O_POS(), O_EL, C_AZ, H_FOV, 0, W, H);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verticalFieldOfViewIsCorrect() {
|
||||
PanoramaParameters p =
|
||||
new PanoramaParameters(O_POS(), O_EL, C_AZ, toRadians(60), MAX_D, 601, 201);
|
||||
assertEquals(p.verticalFieldOfView(), toRadians(20), 1e-10);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void azimuthForXFailsForNegativeX() {
|
||||
PanoramaParameters p =
|
||||
new PanoramaParameters(O_POS(), O_EL, C_AZ, H_FOV, MAX_D, W, H);
|
||||
p.azimuthForX(-1);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void azimuthForXFailsForTooBigX() {
|
||||
PanoramaParameters p =
|
||||
new PanoramaParameters(O_POS(), O_EL, C_AZ, H_FOV, MAX_D, W, H);
|
||||
p.azimuthForX(W + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void azimuthForXWorksForFullCircle() {
|
||||
int centralAzDeg = 90;
|
||||
PanoramaParameters p =
|
||||
new PanoramaParameters(O_POS(), O_EL, toRadians(centralAzDeg), Math2.PI2, MAX_D, 361, 201);
|
||||
for (int azDeg = 0; azDeg < 360; ++azDeg) {
|
||||
double expectedAz = toRadians(floorMod(azDeg - centralAzDeg, 360));
|
||||
double actualAz = p.azimuthForX(azDeg);
|
||||
assertEquals(expectedAz, actualAz, 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void xForAzimuthFailsForTooSmallAzimuth() {
|
||||
PanoramaParameters p =
|
||||
new PanoramaParameters(O_POS(), O_EL, toRadians(10), toRadians(40), MAX_D, W, H);
|
||||
p.xForAzimuth(toRadians(349.99));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void xForAzimuthFailsForTooBigAzimuth() {
|
||||
PanoramaParameters p =
|
||||
new PanoramaParameters(O_POS(), O_EL, toRadians(10), toRadians(40), MAX_D, W, H);
|
||||
p.xForAzimuth(toRadians(50.01));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void altitudeForYFailsForNegativeY() {
|
||||
PanoramaParameters p =
|
||||
new PanoramaParameters(O_POS(), O_EL, C_AZ, H_FOV, MAX_D, W, H);
|
||||
p.altitudeForY(-1);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void altitueForYFailsForTooBigY() {
|
||||
PanoramaParameters p =
|
||||
new PanoramaParameters(O_POS(), O_EL, C_AZ, H_FOV, MAX_D, W, H);
|
||||
p.altitudeForY(H + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void altitudeForYWorks() {
|
||||
int height = 201;
|
||||
PanoramaParameters p =
|
||||
new PanoramaParameters(O_POS(), O_EL, C_AZ, toRadians(60), MAX_D, 601, height);
|
||||
double halfVerticalFOV = toRadians(20) / 2d;
|
||||
double delta = toRadians(0.1);
|
||||
for (int y = 0; y < height; ++y) {
|
||||
assertEquals(halfVerticalFOV - y * delta, p.altitudeForY(y), 1e-9);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void yForAltitudeFailsForTooSmallAltitude() {
|
||||
PanoramaParameters p =
|
||||
new PanoramaParameters(O_POS(), O_EL, C_AZ, toRadians(60), MAX_D, 601, 201);
|
||||
p.yForAltitude(toRadians(-10.01));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void yForAltitudeFailsForTooBigAltitude() {
|
||||
PanoramaParameters p =
|
||||
new PanoramaParameters(O_POS(), O_EL, C_AZ, toRadians(60), MAX_D, 601, 201);
|
||||
p.yForAltitude(toRadians(10.01));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void azimuthForXAndXForAzimuthAreInverse() {
|
||||
PanoramaParameters p =
|
||||
new PanoramaParameters(O_POS(), O_EL, C_AZ, toRadians(60), MAX_D, 601, 201);
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
int x = 1 + rng.nextInt(600);
|
||||
assertEquals(x, p.xForAzimuth(p.azimuthForX(x)), 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void altitudeForYAndYForAltitudeAreInverse() {
|
||||
PanoramaParameters p =
|
||||
new PanoramaParameters(O_POS(), O_EL, C_AZ, toRadians(60), MAX_D, 601, 201);
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
int x = 1 + rng.nextInt(200);
|
||||
assertEquals(x, p.yForAltitude(p.altitudeForY(x)), 1e-10);
|
||||
}
|
||||
}
|
||||
}
|
104
Alpano/tests/ch/epfl/alpano/PanoramaTestP.java
Normal file
@@ -0,0 +1,104 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
import static ch.epfl.test.TestRandomizer.newRandom;
|
||||
import static java.lang.Math.toRadians;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PanoramaTestP{
|
||||
private static PanoramaParameters PARAMS() {
|
||||
return new PanoramaParameters(
|
||||
new GeoPoint(toRadians(46), toRadians(6)),
|
||||
1000,
|
||||
toRadians(180),
|
||||
toRadians(60),
|
||||
100_000,
|
||||
9,
|
||||
7);
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void builderFailsWithNullParameters() {
|
||||
new Panorama.Builder(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void builderConstructorCorrectlyInitializesSamples() {
|
||||
Panorama p = new Panorama.Builder(PARAMS()).build();
|
||||
assertEquals(Float.POSITIVE_INFINITY, p.distanceAt(0, 0), 0);
|
||||
assertEquals(0, p.longitudeAt(0, 0), 0);
|
||||
assertEquals(0, p.latitudeAt(0, 0), 0);
|
||||
assertEquals(0, p.elevationAt(0, 0), 0);
|
||||
assertEquals(0, p.slopeAt(0, 0), 0);
|
||||
}
|
||||
|
||||
@Test(expected = IndexOutOfBoundsException.class)
|
||||
public void setDistanceAtFailsWithInvalidIndex() {
|
||||
Panorama.Builder b = new Panorama.Builder(PARAMS());
|
||||
b.setDistanceAt(10, 0, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setLongitudeAtReturnsThis() {
|
||||
Panorama.Builder b = new Panorama.Builder(PARAMS());
|
||||
assertSame(b, b.setLongitudeAt(0, 0, 1));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void setSlopeAtFailsAfterBuild() {
|
||||
Panorama.Builder b = new Panorama.Builder(PARAMS());
|
||||
b.build();
|
||||
b.setSlopeAt(0, 0, 0);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void buildFailsAfterBuild() {
|
||||
Panorama.Builder b = new Panorama.Builder(PARAMS());
|
||||
b.build();
|
||||
b.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parametersReturnsParameters() {
|
||||
PanoramaParameters ps = PARAMS();
|
||||
Panorama p = new Panorama.Builder(ps).build();
|
||||
assertSame(ps, p.parameters());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void builderSettersWork() {
|
||||
PanoramaParameters ps = PARAMS();
|
||||
float[] values = new float[ps.width() * ps.height()];
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < values.length; ++i)
|
||||
values[i] = rng.nextFloat() + 0.5f;
|
||||
|
||||
Panorama.Builder b = new Panorama.Builder(ps);
|
||||
for (int x = 0; x < ps.width(); ++x) {
|
||||
for (int y = 0; y < ps.height(); ++y) {
|
||||
float v = values[y + x * ps.height()];
|
||||
b.setDistanceAt(x, y, v)
|
||||
.setElevationAt(x, y, v)
|
||||
.setLatitudeAt(x, y, v)
|
||||
.setLongitudeAt(x, y, v)
|
||||
.setSlopeAt(x, y, v);
|
||||
}
|
||||
}
|
||||
|
||||
Panorama p = b.build();
|
||||
for (int x = 0; x < ps.width(); ++x) {
|
||||
for (int y = 0; y < ps.height(); ++y) {
|
||||
float v = values[y + x * ps.height()];
|
||||
assertEquals(v, p.distanceAt(x, y), 0);
|
||||
assertEquals(v, p.elevationAt(x, y), 0);
|
||||
assertEquals(v, p.latitudeAt(x, y), 0);
|
||||
assertEquals(v, p.longitudeAt(x, y), 0);
|
||||
assertEquals(v, p.slopeAt(x, y), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
47
Alpano/tests/ch/epfl/alpano/PreconditionsTest.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
import static ch.epfl.alpano.Preconditions.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PreconditionsTest {
|
||||
////////// checkArgument (1 argument)
|
||||
|
||||
@Test
|
||||
public void checkArgument1SucceedsForTrue() {
|
||||
checkArgument(true);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void checkArgument1ThrowsForFalse() {
|
||||
checkArgument(false);
|
||||
}
|
||||
|
||||
////////// checkArgument (2 arguments)
|
||||
|
||||
@Test
|
||||
public void checkArgument2SucceedsForTrue() {
|
||||
checkArgument(true, "");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void checkArgument2ThrowsForFalse() {
|
||||
checkArgument(false, "");
|
||||
}
|
||||
|
||||
////////// checkNonNul (1 arguments)
|
||||
|
||||
@Test
|
||||
public void checkNonNulSuccess() {
|
||||
checkNonNul(1, "");
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void checkNonNulThrowsForZero() {
|
||||
checkNonNul(0, "");
|
||||
}
|
||||
|
||||
////////// checkNonNul (1 arguments)
|
||||
|
||||
|
||||
}
|
26
Alpano/tests/ch/epfl/alpano/TestDemForPanoramaComp.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package ch.epfl.alpano;
|
||||
|
||||
|
||||
|
||||
import ch.epfl.alpano.dem.DiscreteElevationModel;
|
||||
|
||||
public class TestDemForPanoramaComp implements DiscreteElevationModel {
|
||||
|
||||
private final Interval2D extent;
|
||||
|
||||
public TestDemForPanoramaComp(Interval2D extent) {
|
||||
this.extent = extent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception { }
|
||||
|
||||
@Override
|
||||
public Interval2D extent() { return extent; }
|
||||
|
||||
@Override
|
||||
public double elevationSample(int x, int y) {
|
||||
|
||||
return x*x-y*y;
|
||||
}
|
||||
}
|
@@ -0,0 +1,117 @@
|
||||
package ch.epfl.alpano.dem;
|
||||
|
||||
import static ch.epfl.test.TestRandomizer.RANDOM_ITERATIONS;
|
||||
import static ch.epfl.test.TestRandomizer.newRandom;
|
||||
import static java.lang.Math.toRadians;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ch.epfl.alpano.Interval1D;
|
||||
import ch.epfl.alpano.Interval2D;
|
||||
|
||||
public class CompositeDiscreteElevationModelTest {
|
||||
private final static Interval2D ext1 = new Interval2D(
|
||||
new Interval1D(-100_000, 100_000),
|
||||
new Interval1D(0, 100_000));
|
||||
private final static Interval2D ext2 = new Interval2D(
|
||||
new Interval1D(-100_000, 100_000),
|
||||
new Interval1D(100_001, 200_000));
|
||||
private final static Interval2D ext12 = new Interval2D(
|
||||
new Interval1D(-100_000, 100_000),
|
||||
new Interval1D(0, 200_000));
|
||||
private final static Interval2D ext3 = new Interval2D(
|
||||
new Interval1D(0, 99_999),
|
||||
new Interval1D(0, 100_001));
|
||||
|
||||
@Test
|
||||
public void samplesPerRadiansHasCorrectValue() {
|
||||
assertEquals(206264.80624709636, DiscreteElevationModel.SAMPLES_PER_RADIAN, 1e-8);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sampleIndexWorksOnRandomValues() {
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
int arcSeconds = rng.nextInt(2_000_000) - 1_000_000;
|
||||
double angle = toRadians(arcSeconds / 3_600d);
|
||||
assertEquals(arcSeconds, DiscreteElevationModel.sampleIndex(angle), 1e-5);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void unionFailsIfExtentsNotUnionable() {
|
||||
ConstantElevationDEM dem1 = new ConstantElevationDEM(ext1, 0);
|
||||
ConstantElevationDEM dem2 = new ConstantElevationDEM(ext3, 0);
|
||||
dem1.union(dem2);
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
@Test
|
||||
public void extentOfUnionIsUnionOfExtent() {
|
||||
ConstantElevationDEM dem1 = new ConstantElevationDEM(ext1, 0);
|
||||
ConstantElevationDEM dem2 = new ConstantElevationDEM(ext2, 0);
|
||||
DiscreteElevationModel dem12 = dem1.union(dem2);
|
||||
assertEquals(ext12, dem12.extent());
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void elevationSampleFailsWhenOutsideOfExtent() {
|
||||
ConstantElevationDEM dem1 = new ConstantElevationDEM(ext1, 0);
|
||||
ConstantElevationDEM dem2 = new ConstantElevationDEM(ext2, 0);
|
||||
DiscreteElevationModel dem12 = dem1.union(dem2);
|
||||
dem12.elevationSample(0, 200_001);
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
@Test
|
||||
public void elevationSampleWorksOnBothSubDEMs() {
|
||||
ConstantElevationDEM dem1 = new ConstantElevationDEM(ext1, 1);
|
||||
ConstantElevationDEM dem2 = new ConstantElevationDEM(ext2, 2);
|
||||
DiscreteElevationModel dem12 = dem1.union(dem2);
|
||||
assertEquals(1, dem12.elevationSample(-100_000, 0), 0);
|
||||
assertEquals(1, dem12.elevationSample(100_000, 0), 0);
|
||||
assertEquals(1, dem12.elevationSample(100_000, 100_000), 0);
|
||||
assertEquals(1, dem12.elevationSample(-100_000, 100_000), 0);
|
||||
assertEquals(2, dem12.elevationSample(-100_000, 100_001), 0);
|
||||
assertEquals(2, dem12.elevationSample(100_000, 100_001), 0);
|
||||
assertEquals(2, dem12.elevationSample(100_000, 200_000), 0);
|
||||
assertEquals(2, dem12.elevationSample(-100_000, 200_000), 0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
@Test
|
||||
public void closeClosesBothSubDEMs() throws Exception {
|
||||
ConstantElevationDEM dem1 = new ConstantElevationDEM(ext1, 0);
|
||||
ConstantElevationDEM dem2 = new ConstantElevationDEM(ext2, 0);
|
||||
DiscreteElevationModel dem12 = dem1.union(dem2);
|
||||
dem12.close();
|
||||
assertTrue(dem1.isClosed);
|
||||
assertTrue(dem2.isClosed);
|
||||
}
|
||||
}
|
||||
|
||||
class ConstantElevationDEM implements DiscreteElevationModel {
|
||||
private final Interval2D extent;
|
||||
private final double elevation;
|
||||
boolean isClosed = false;
|
||||
|
||||
public ConstantElevationDEM(Interval2D extent, double elevation) {
|
||||
this.extent = extent;
|
||||
this.elevation = elevation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception { isClosed = true; }
|
||||
|
||||
@Override
|
||||
public Interval2D extent() { return extent; }
|
||||
|
||||
@Override
|
||||
public double elevationSample(int x, int y) { return elevation; }
|
||||
}
|
@@ -0,0 +1,170 @@
|
||||
package ch.epfl.alpano.dem;
|
||||
|
||||
import static ch.epfl.test.TestRandomizer.RANDOM_ITERATIONS;
|
||||
import static ch.epfl.test.TestRandomizer.newRandom;
|
||||
import static java.lang.Math.toDegrees;
|
||||
import static java.lang.Math.toRadians;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ch.epfl.alpano.GeoPoint;
|
||||
import ch.epfl.alpano.Interval1D;
|
||||
import ch.epfl.alpano.Interval2D;
|
||||
|
||||
public class ContinuousElevationModelTest {
|
||||
private final static Interval2D EXT_100_100 = new Interval2D(
|
||||
new Interval1D(0, 100),
|
||||
new Interval1D(0, 100));
|
||||
|
||||
private final static Interval2D EXT_13_13 = new Interval2D(
|
||||
new Interval1D(0, 13),
|
||||
new Interval1D(0, 13));
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void constructorFailsWithNullDEM() {
|
||||
new ContinuousElevationModel(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void elevationAtReturns0OutsideOfExtent() {
|
||||
DiscreteElevationModel dDEM = new ConstantElevationDEM(EXT_100_100, 1000);
|
||||
ContinuousElevationModel cDEM = new ContinuousElevationModel(dDEM);
|
||||
assertEquals(0, cDEM.elevationAt(pointForSampleIndex(101, 0)), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void elevationAtReturnsCorrectElevationInsideExtent() {
|
||||
double elevation = 1000;
|
||||
DiscreteElevationModel dDEM = new ConstantElevationDEM(EXT_100_100, elevation);
|
||||
ContinuousElevationModel cDEM = new ContinuousElevationModel(dDEM);
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double x = rng.nextDouble() * 100d, y = rng.nextDouble() * 100d;
|
||||
assertEquals(elevation, cDEM.elevationAt(pointForSampleIndex(x, y)), 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void elevationAtInterpolatesJustOutsideExtent() {
|
||||
DiscreteElevationModel dDEM = new ConstantElevationDEM(EXT_100_100, 1000);
|
||||
ContinuousElevationModel cDEM = new ContinuousElevationModel(dDEM);
|
||||
assertEquals(500, cDEM.elevationAt(pointForSampleIndex(100.5, 10)), 1e-10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void elevationAtReturnsCorrectInterpolatedElevation() {
|
||||
DiscreteElevationModel dDEM = new ConstantSlopeDEM(EXT_100_100);
|
||||
ContinuousElevationModel cDEM = new ContinuousElevationModel(dDEM);
|
||||
Random rng = new Random();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double x = rng.nextDouble() * 100;
|
||||
double y = rng.nextDouble() * 100;
|
||||
assertEquals((x + y) * ConstantSlopeDEM.INTER_SAMPLE_DISTANCE, cDEM.elevationAt(pointForSampleIndex(x, y)), 1e-6);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void elevationAtStaysWithinBoundsOnRandomTerrain() {
|
||||
int maxElevation = 1000;
|
||||
DiscreteElevationModel dDEM = new RandomElevationDEM(EXT_13_13, maxElevation);
|
||||
ContinuousElevationModel cDEM = new ContinuousElevationModel(dDEM);
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double x = rng.nextDouble() * dDEM.extent().iX().size();
|
||||
double y = rng.nextDouble() * dDEM.extent().iY().size();
|
||||
double e = cDEM.elevationAt(pointForSampleIndex(x, y));
|
||||
assertTrue(0 <= e && e <= maxElevation);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void slopeAtReturnsCorrectInterpolatedSlope() {
|
||||
DiscreteElevationModel dDEM = new ConstantSlopeDEM(EXT_100_100);
|
||||
ContinuousElevationModel cDEM = new ContinuousElevationModel(dDEM);
|
||||
Random rng = new Random();
|
||||
double expectedSlope = Math.acos(1 / Math.sqrt(3));
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double x = 5 + rng.nextDouble() * 90;
|
||||
double y = 5 + rng.nextDouble() * 90;
|
||||
assertEquals(expectedSlope, cDEM.slopeAt(pointForSampleIndex(x, y)), 1e-4);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void slopeAtStaysWithinBoundsOnRandomTerrain() {
|
||||
int maxElevation = 1000;
|
||||
DiscreteElevationModel dDEM = new RandomElevationDEM(EXT_13_13, maxElevation);
|
||||
ContinuousElevationModel cDEM = new ContinuousElevationModel(dDEM);
|
||||
Random rng = newRandom();
|
||||
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
|
||||
double x = rng.nextDouble() * dDEM.extent().iX().size();
|
||||
double y = rng.nextDouble() * dDEM.extent().iY().size();
|
||||
double e = toDegrees(cDEM.slopeAt(pointForSampleIndex(x, y)));
|
||||
assertTrue(0 <= e && e < 90);
|
||||
}
|
||||
}
|
||||
|
||||
private static GeoPoint pointForSampleIndex(double x, double y) {
|
||||
return new GeoPoint(toRadians(x / 3600d), toRadians(y / 3600d));
|
||||
}
|
||||
}
|
||||
|
||||
class RandomElevationDEM implements DiscreteElevationModel {
|
||||
private final Interval2D extent;
|
||||
private final double[][] elevations;
|
||||
|
||||
public RandomElevationDEM(Interval2D extent, int maxElevation) {
|
||||
this.extent = extent;
|
||||
this.elevations = randomElevations(extent.iX().size(), extent.iY().size(), maxElevation);
|
||||
}
|
||||
|
||||
private static double[][] randomElevations(int width, int height, int maxElevation) {
|
||||
Random rng = newRandom();
|
||||
double[][] es = new double[width][height];
|
||||
for (int x = 0; x < width; ++x) {
|
||||
for (int y = 0; y < height; ++y) {
|
||||
es[x][y] = rng.nextInt(maxElevation + 1);
|
||||
}
|
||||
}
|
||||
return es;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Interval2D extent() {
|
||||
return extent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double elevationSample(int x, int y) {
|
||||
return elevations[x][y];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception { }
|
||||
}
|
||||
|
||||
class ConstantSlopeDEM implements DiscreteElevationModel {
|
||||
public final static double INTER_SAMPLE_DISTANCE =
|
||||
2d * Math.PI * 6_371_000d / (3600d * 360d);
|
||||
|
||||
private final Interval2D extent;
|
||||
|
||||
public ConstantSlopeDEM(Interval2D extent) {
|
||||
this.extent = extent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Interval2D extent() { return extent; }
|
||||
|
||||
@Override
|
||||
public double elevationSample(int x, int y) {
|
||||
return (x + y) * INTER_SAMPLE_DISTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {}
|
||||
}
|
70
Alpano/tests/ch/epfl/alpano/dem/DrawElevationProfile.java
Normal file
@@ -0,0 +1,70 @@
|
||||
package ch.epfl.alpano.dem;
|
||||
|
||||
import static java.lang.Math.toRadians;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import ch.epfl.alpano.GeoPoint;
|
||||
|
||||
final class DrawElevationProfile {
|
||||
final static File HGT_FILE = new File("HGT"+File.separatorChar+"N46E006.hgt");
|
||||
final static double MAX_ELEVATION = 1_500;
|
||||
final static int LENGTH = 111_000;
|
||||
final static double AZIMUTH = toRadians(27.97);
|
||||
final static double LONGITUDE = toRadians(6.15432);
|
||||
final static double LATITUDE = toRadians(46.20562);
|
||||
final static int WIDTH = 800, HEIGHT = 100;
|
||||
|
||||
public static void main(String[] as) throws Exception {
|
||||
DiscreteElevationModel dDEM =
|
||||
new HgtDiscreteElevationModel(HGT_FILE);
|
||||
ContinuousElevationModel cDEM =
|
||||
new ContinuousElevationModel(dDEM);
|
||||
GeoPoint o =
|
||||
new GeoPoint(LONGITUDE, LATITUDE);
|
||||
ElevationProfile p1 =
|
||||
new ElevationProfile(cDEM, o, AZIMUTH, (int)(LENGTH/3));
|
||||
GeoPoint gP1 = p1.positionAt((int)LENGTH/3);
|
||||
ElevationProfile p2 =
|
||||
new ElevationProfile(cDEM, p1.positionAt((int)LENGTH/3), AZIMUTH+toRadians(6.0),2*((int)LENGTH/3));
|
||||
GeoPoint gP2 = p2.positionAt(2*((int)LENGTH/3));
|
||||
|
||||
|
||||
ElevationProfile p3 = new ElevationProfile (cDEM,p2.positionAt(2*((int)LENGTH/3)), AZIMUTH, LENGTH);
|
||||
|
||||
|
||||
ArrayList<GeoPoint> trekkingSpots = new ArrayList<GeoPoint>(Arrays.asList(o,gP1,gP2));
|
||||
ArrayList<ElevationProfile> profiles= new ArrayList<ElevationProfile>();
|
||||
for (int index = 0; index < trekkingSpots.size()-1; index++){
|
||||
GeoPoint current= trekkingSpots.get(index);
|
||||
GeoPoint next = trekkingSpots.get(index+1);
|
||||
ElevationProfile evP= new ElevationProfile(cDEM, current,current.azimuthTo(next), current.distanceTo(next));
|
||||
profiles.add(evP);
|
||||
}
|
||||
|
||||
CompositElevationProfile p = new CompositElevationProfile(profiles);
|
||||
|
||||
int BLACK = 0x00_00_00, WHITE = 0xFF_FF_FF;
|
||||
|
||||
BufferedImage i =
|
||||
new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
|
||||
for (int x = 0; x < WIDTH; ++x) {
|
||||
double pX = x * (double) LENGTH / (WIDTH - 1);
|
||||
double pY = p.elevationAt(pX);
|
||||
int yL = (int)((pY / MAX_ELEVATION) * (HEIGHT - 1));
|
||||
for (int y = 0; y < HEIGHT; ++y) {
|
||||
int color = y < yL ? BLACK : WHITE;
|
||||
i.setRGB(x, HEIGHT - 1 - y, color);
|
||||
}
|
||||
}
|
||||
dDEM.close();
|
||||
|
||||
ImageIO.write(i, "png", new File("tests/ch/epfl/alpano/dem/profile.png"));
|
||||
}
|
||||
|
||||
}
|
83
Alpano/tests/ch/epfl/alpano/dem/DrawHgtDEM.java
Normal file
@@ -0,0 +1,83 @@
|
||||
package ch.epfl.alpano.dem;
|
||||
|
||||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import ch.epfl.alpano.GeoPoint;
|
||||
import static java.lang.Math.toRadians;
|
||||
|
||||
final class DrawHgtDEM {
|
||||
final static File HGT_FILE = new File("HGT"+File.separatorChar+"N46E006.hgt");
|
||||
final static double ORIGIN_LON = toRadians(6.25);
|
||||
final static double ORIGIN_LAT = toRadians(46.25);
|
||||
final static double WIDTH = toRadians(0.5);
|
||||
final static int IMAGE_SIZE = 300;
|
||||
final static double MIN_ELEVATION = 200;
|
||||
final static double MAX_ELEVATION = 1_500;
|
||||
|
||||
public static void main(String[] as) throws Exception {
|
||||
DiscreteElevationModel dDEM =
|
||||
new HgtDiscreteElevationModel(HGT_FILE);
|
||||
ContinuousElevationModel cDEM =
|
||||
new ContinuousElevationModel(dDEM);
|
||||
|
||||
double step = WIDTH / (IMAGE_SIZE - 1);
|
||||
BufferedImage i = new BufferedImage(IMAGE_SIZE,
|
||||
IMAGE_SIZE,
|
||||
BufferedImage.TYPE_INT_RGB);
|
||||
for (int x = 0; x < IMAGE_SIZE; ++x) {
|
||||
double lon = ORIGIN_LON + x * step;
|
||||
for (int y = 0; y < IMAGE_SIZE; ++y) {
|
||||
double lat = ORIGIN_LAT + y * step;
|
||||
GeoPoint p = new GeoPoint(lon, lat);
|
||||
double el =
|
||||
(cDEM.elevationAt(p) - MIN_ELEVATION)
|
||||
/ (MAX_ELEVATION - MIN_ELEVATION);
|
||||
i.setRGB(x, IMAGE_SIZE - 1 - y, gray(el));
|
||||
}
|
||||
}
|
||||
dDEM.close();
|
||||
|
||||
|
||||
ImageIO.write(i, "png", new File("tests/ch/epfl/alpano/dem/dem.png"));
|
||||
}
|
||||
|
||||
public static void drawDem(ContinuousElevationModel cDem){
|
||||
|
||||
double step = WIDTH / (IMAGE_SIZE - 1);
|
||||
BufferedImage i = new BufferedImage(IMAGE_SIZE,
|
||||
IMAGE_SIZE,
|
||||
BufferedImage.TYPE_INT_RGB);
|
||||
for (int x = 0; x < IMAGE_SIZE; ++x) {
|
||||
double lon = ORIGIN_LON + x * step;
|
||||
for (int y = 0; y < IMAGE_SIZE; ++y) {
|
||||
double lat = ORIGIN_LAT + y * step;
|
||||
GeoPoint p = new GeoPoint(lon, lat);
|
||||
double el =
|
||||
(cDem.elevationAt(p) - MIN_ELEVATION)
|
||||
/ (MAX_ELEVATION - MIN_ELEVATION);
|
||||
i.setRGB(x, IMAGE_SIZE - 1 - y, gray(el));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
try {
|
||||
ImageIO.write(i, "png", new File("tests/ch/epfl/alpano/dem/dem.png"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static int gray(double v) {
|
||||
double clampedV = max(0, min(v, 1));
|
||||
int gray = (int) (255.9999 * clampedV);
|
||||
return (gray << 16) | (gray << 8) | gray;
|
||||
}
|
||||
|
||||
}
|
50
Alpano/tests/ch/epfl/alpano/dem/DrawHgtDEM2.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package ch.epfl.alpano.dem;
|
||||
|
||||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import javax.imageio.ImageIO;
|
||||
import ch.epfl.alpano.GeoPoint;
|
||||
|
||||
import static java.lang.Math.toRadians;
|
||||
|
||||
final class DrawHgtDEM2 {
|
||||
final static double ORIGIN_LON = toRadians(6.0);
|
||||
final static double ORIGIN_LAT = toRadians(45.0);
|
||||
final static double WIDTH = toRadians(0.1);
|
||||
final static int IMAGE_SIZE = 1200;
|
||||
final static double MIN_ELEVATION = 00;
|
||||
final static double MAX_ELEVATION = 500;
|
||||
|
||||
public static void main(String[] as) throws Exception {
|
||||
DiscreteElevationModel dDEM = new HgtDiscreteElevationModel(null);
|
||||
ContinuousElevationModel cDEM =
|
||||
new ContinuousElevationModel(dDEM);
|
||||
|
||||
double step = WIDTH / (IMAGE_SIZE - 1);
|
||||
BufferedImage i = new BufferedImage(IMAGE_SIZE,
|
||||
IMAGE_SIZE, BufferedImage.TYPE_INT_RGB);
|
||||
for (int x = 0; x < IMAGE_SIZE; ++x) {
|
||||
double lon = ORIGIN_LON + x * step;
|
||||
for (int y = 0; y < IMAGE_SIZE; ++y) {
|
||||
double lat = ORIGIN_LAT + y * step;
|
||||
GeoPoint p = new GeoPoint(lon, lat);
|
||||
double el =
|
||||
(cDEM.elevationAt(p) - MIN_ELEVATION)
|
||||
/ (MAX_ELEVATION - MIN_ELEVATION);
|
||||
i.setRGB(x, IMAGE_SIZE - 1 - y, gray(el));
|
||||
}
|
||||
}
|
||||
dDEM.close();
|
||||
ImageIO.write(i, "png", new File("tests/ch/epfl/alpano/dem/dem2.png"));
|
||||
}
|
||||
|
||||
private static int gray(double v) {
|
||||
double clampedV = max(0, min(v, 1));
|
||||
int gray = (int) (255.9999 * clampedV);
|
||||
return (gray << 16) | (gray << 8) | gray;
|
||||
}
|
||||
|
||||
}
|
49
Alpano/tests/ch/epfl/alpano/dem/ElevationProfileTest.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package ch.epfl.alpano.dem;
|
||||
|
||||
import static java.lang.Math.toRadians;
|
||||
import static org.junit.Assert.*;
|
||||
import java.io.File;
|
||||
import org.junit.Test;
|
||||
|
||||
import ch.epfl.alpano.GeoPoint;
|
||||
|
||||
public class ElevationProfileTest {
|
||||
|
||||
final static File HGT_FILE = new File("HGT"+File.separatorChar+"N46E006.hgt");
|
||||
final static double AZIMUTH = toRadians(45.0);
|
||||
final static double LONGITUDE = toRadians(6.0);
|
||||
final static double LATITUDE = toRadians(46.0);
|
||||
final static int LENGTH = 111_000;
|
||||
|
||||
@Test
|
||||
public void testElevationProfile() {
|
||||
DiscreteElevationModel dDEM =
|
||||
new HgtDiscreteElevationModel(HGT_FILE);
|
||||
ContinuousElevationModel cDEM =
|
||||
new ContinuousElevationModel(dDEM);
|
||||
GeoPoint o =
|
||||
new GeoPoint(LONGITUDE, LATITUDE);
|
||||
ElevationProfile p =
|
||||
new ElevationProfile(cDEM, o, AZIMUTH, LENGTH);
|
||||
|
||||
assertEquals(toRadians(6.09385),p.positionAt(10240).longitude(),0.00001);
|
||||
assertEquals(toRadians(46.06508),p.positionAt(10240).latitude(),0.00001);
|
||||
|
||||
}
|
||||
/*
|
||||
@Test
|
||||
public void testElevationAt() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPositionAt() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSlopeAt() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
*/
|
||||
}
|
134
Alpano/tests/ch/epfl/alpano/dem/ElevationProfileTestP.java
Normal file
@@ -0,0 +1,134 @@
|
||||
package ch.epfl.alpano.dem;
|
||||
|
||||
import static java.lang.Math.PI;
|
||||
import static java.lang.Math.toRadians;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ch.epfl.alpano.GeoPoint;
|
||||
import ch.epfl.alpano.Interval1D;
|
||||
import ch.epfl.alpano.Interval2D;
|
||||
|
||||
public class ElevationProfileTestP {
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void constructorFailsWhenElevationModelIsNull() {
|
||||
new ElevationProfile(null, new GeoPoint(0,0), 0, 100);
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void constructorFailsWhenOriginIsNull() {
|
||||
new ElevationProfile(newConstantSlopeDEM(), null, 0, 100);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorFailsWhenAzimuthIsNotCanonical() {
|
||||
new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), 6.3, 100);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorFailsWhenLengthIsZero() {
|
||||
new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), 0, 0);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void elevationAtFailsWhenXIsTooBig() {
|
||||
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), 0, 100);
|
||||
p.elevationAt(101);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void elevationAtWorksOnConstantSlopeDEMGoingNorth() {
|
||||
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), 0, 100_000);
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
double x = 100d * i;
|
||||
assertEquals(x, p.elevationAt(x), 1e-5);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void elevationAtWorksOnConstantSlopeDEMGoingSouth() {
|
||||
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), PI, 100_000);
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
double x = 100d * i;
|
||||
assertEquals(-x, p.elevationAt(x), 1e-5);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void elevationAtWorksOnConstantSlopeDEMGoingEast() {
|
||||
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), PI/2d, 100_000);
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
double x = 100d * i;
|
||||
assertEquals(x, p.elevationAt(x), 1e-5);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void elevationAtWorksOnConstantSlopeDEMGoingWest() {
|
||||
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), 3d*PI/2d, 100_000);
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
double x = 100d * i;
|
||||
assertEquals(-x, p.elevationAt(x), 1e-5);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void positionAtFailsWhenXIsTooBig() {
|
||||
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), 0, 100);
|
||||
p.positionAt(101);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void positionAtProducesConstantLongitudeWhenGoingNorth() {
|
||||
double lon = toRadians(3);
|
||||
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(lon,toRadians(40)), 0, 100_000);
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
double x = 500d * i;
|
||||
assertEquals(lon, p.positionAt(x).longitude(), 1e-5);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void positionAtProducesConstantLongitudeWhenGoingSouth() {
|
||||
double lon = toRadians(3);
|
||||
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(lon,toRadians(40)), PI, 100_000);
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
double x = 500d * i;
|
||||
assertEquals(lon, p.positionAt(x).longitude(), 1e-5);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void positionAtProducesConstantLatitudeWhenGoingEast() {
|
||||
double lat = toRadians(40);
|
||||
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(toRadians(3),lat), PI/2d, 100_000);
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
double x = 500d * i;
|
||||
assertEquals(lat, p.positionAt(x).latitude(), 1e-4);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void positionAtProducesConstantLatitudeWhenGoingWest() {
|
||||
double lat = toRadians(40);
|
||||
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(toRadians(3),lat), 3d*PI/2d, 100_000);
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
double x = 500d * i;
|
||||
assertEquals(lat, p.positionAt(x).latitude(), 1e-4);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void slopeAtFailsWhenXIsNegative() {
|
||||
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), 0, 100);
|
||||
p.positionAt(-1);
|
||||
}
|
||||
|
||||
private static ContinuousElevationModel newConstantSlopeDEM() {
|
||||
Interval2D extent = new Interval2D(
|
||||
new Interval1D(-10_000, 10_000),
|
||||
new Interval1D(-10_000, 10_000));
|
||||
return new ContinuousElevationModel(new ConstantSlopeDEM(extent));
|
||||
}
|
||||
}
|
@@ -0,0 +1,77 @@
|
||||
package ch.epfl.alpano.dem;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static ch.epfl.alpano.Preconditions.checkArgument;
|
||||
import java.io.File;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class HgtDiscreteElevationModelTest {
|
||||
|
||||
@Test
|
||||
public void testHgtDiscreteElevationModel() {
|
||||
String[] files = {"N45E006.hgt","N45E007.hgt","N45E008.hgt","N45E009.hgt",
|
||||
"N45E010.hgt","N45E011.hgt","N46E006.hgt","N46E007.hgt",
|
||||
"N46E008.hgt","N46E009.hgt","N46E010.hgt","N46E011.hgt",
|
||||
"N47E006.hgt","N47E007.hgt","N47E008.hgt","N47E009.hgt",
|
||||
"N47E010.hgt","N47E011.hgt","N00E000.hgt","S89W120"};
|
||||
File file;
|
||||
for(String txt: files){
|
||||
file = new File("HGT"+File.separatorChar+txt);
|
||||
if(file.exists())
|
||||
new HgtDiscreteElevationModel(file);
|
||||
}
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testHgtDiscreteElevationModelFails() {
|
||||
String[] files = {"N45E180.hgt","N45E007.hgt",};
|
||||
File file;
|
||||
for(String txt: files){
|
||||
file = new File("HGT"+File.separatorChar+txt);
|
||||
new HgtDiscreteElevationModel(file);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkFileNameSuccess() {
|
||||
assertTrue(checkFileName("S00E000.hgt")!=null);
|
||||
assertTrue(checkFileName("N00E000.hgt")!=null);
|
||||
assertTrue(checkFileName("S00W129.hgt")!=null);
|
||||
assertTrue(checkFileName("N00W000.hgt")!=null);
|
||||
assertTrue(checkFileName("S69E139.hgt")!=null);
|
||||
assertTrue(checkFileName("S90W180.hgt")!=null);
|
||||
assertTrue(checkFileName("N90E180.hgt")!=null);
|
||||
assertTrue(checkFileName("S90W180.hgt")!=null);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void checkFileNameFails() {
|
||||
checkFileName("E46E006.hgt");
|
||||
checkFileName("N4gE006.hgt");
|
||||
checkFileName("N46E0g6.hgt");
|
||||
checkFileName("N46E006lhgt");
|
||||
checkFileName("N46E006.hGT");
|
||||
checkFileName("N4gE006.hgt");
|
||||
checkFileName("N46E0g6.hgt");
|
||||
checkFileName("N46E006phgt");
|
||||
checkFileName("Q99E006.hGT");
|
||||
}
|
||||
|
||||
private static final Matcher checkFileName(String txt){
|
||||
final Pattern P = Pattern.compile("([NS])(\\d{2})([EW])(\\d{3})\\.hgt");
|
||||
|
||||
Matcher m = P.matcher(txt);
|
||||
|
||||
checkArgument((txt.length()==11 && m.find()));
|
||||
int lat = Integer.parseInt(m.group(2));
|
||||
int lon = Integer.parseInt(m.group(4));
|
||||
checkArgument(!(lat>90 || lon>180 ));
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,154 @@
|
||||
package ch.epfl.alpano.dem;
|
||||
|
||||
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
||||
import static java.nio.file.StandardOpenOption.CREATE_NEW;
|
||||
import static java.nio.file.StandardOpenOption.READ;
|
||||
import static java.nio.file.StandardOpenOption.WRITE;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ShortBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileChannel.MapMode;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ch.epfl.alpano.Interval1D;
|
||||
import ch.epfl.alpano.Interval2D;
|
||||
|
||||
public class HgtDiscreteElevationModelTestP {
|
||||
private final static long HGT_FILE_SIZE = 3601L * 3601L * 2L;
|
||||
private static Path FAKE_HGT_DIR, FAKE_HGT_FILE;
|
||||
|
||||
@BeforeClass
|
||||
public static void createFakeHgtFiles() throws IOException {
|
||||
Path fakeHgtDir = Files.createTempDirectory("hgt");
|
||||
|
||||
Path fakeHgtFile = fakeHgtDir.resolve("empty.hgt");
|
||||
try (FileChannel c = FileChannel.open(fakeHgtFile, CREATE_NEW, READ, WRITE)) {
|
||||
// make sure the empty hgt file has the right size
|
||||
c.map(MapMode.READ_WRITE, 0, HGT_FILE_SIZE).asShortBuffer();
|
||||
}
|
||||
|
||||
FAKE_HGT_FILE = fakeHgtFile;
|
||||
FAKE_HGT_DIR = fakeHgtDir;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void deleteFakeHgtFiles() throws IOException {
|
||||
Files.walkFileTree(FAKE_HGT_DIR, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
Files.delete(file);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
|
||||
if (exc != null)
|
||||
throw exc;
|
||||
Files.delete(dir);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorFailsWithTooShortName() throws Exception {
|
||||
createHgtDemWithFileNamed("N47E010.hg");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorFailsWithInvalidLatitudeLetter() throws Exception {
|
||||
createHgtDemWithFileNamed("N4xE010.hgt");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorFailsWithInvalidLongitudeLetter() throws Exception {
|
||||
createHgtDemWithFileNamed("N47x010.hgt");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorFailsWithInexistantFile() throws Exception {
|
||||
Path p = FAKE_HGT_DIR.resolve("N40E010.hgt");
|
||||
try (DiscreteElevationModel d = new HgtDiscreteElevationModel(p.toFile())) {}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorFailsWithEmptyFile() throws Exception {
|
||||
File f = FAKE_HGT_DIR.resolve("N41E010.hgt").toFile();
|
||||
try (FileOutputStream s = new FileOutputStream(f)) {
|
||||
s.write(0);
|
||||
}
|
||||
try (DiscreteElevationModel d = new HgtDiscreteElevationModel(f)) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWorksInEcuador() throws Exception {
|
||||
createHgtDemWithFileNamed("S03W078.hgt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extentMatchesFileName() throws Exception {
|
||||
int[] lons = new int[] { 1, 7 };
|
||||
int[] lats = new int[] { 1, 47 };
|
||||
for (int lon: lons) {
|
||||
for (int lat: lats) {
|
||||
Interval2D expectedExtent = new Interval2D(
|
||||
new Interval1D(lon * 3600, (lon + 1) * 3600),
|
||||
new Interval1D(lat * 3600, (lat + 1) * 3600));
|
||||
String hgtFileName = String.format("N%02dE%03d.hgt", lat, lon);
|
||||
Path p = copyEmptyHgtFileAs(hgtFileName);
|
||||
try (HgtDiscreteElevationModel dem = new HgtDiscreteElevationModel(p.toFile())) {
|
||||
assertEquals(expectedExtent, dem.extent());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void elevationSampleFailsForIndexNotInExtent() throws Exception {
|
||||
String hgtFileName = "N02E002.hgt";
|
||||
Path p = copyEmptyHgtFileAs(hgtFileName);
|
||||
try (HgtDiscreteElevationModel dem = new HgtDiscreteElevationModel(p.toFile())) {
|
||||
dem.elevationSample(10, 10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void elevationSampleIsCorrectInFourCorners() throws Exception {
|
||||
Path p = FAKE_HGT_DIR.resolve("N01E001.hgt");
|
||||
try (FileChannel c = FileChannel.open(p, CREATE_NEW, READ, WRITE)) {
|
||||
ShortBuffer b = c.map(MapMode.READ_WRITE, 0, HGT_FILE_SIZE).asShortBuffer();
|
||||
b.put(0, (short)1);
|
||||
b.put(3600, (short) 2);
|
||||
b.put(3601 * 3600, (short) 3);
|
||||
b.put(3601 * 3601 - 1, (short) 4);
|
||||
}
|
||||
try (HgtDiscreteElevationModel dem = new HgtDiscreteElevationModel(p.toFile())) {
|
||||
assertEquals(0, dem.elevationSample(4000, 4000), 1e-10);
|
||||
assertEquals(1, dem.elevationSample(3600, 7200), 1e-10);
|
||||
assertEquals(2, dem.elevationSample(7200, 7200), 1e-10);
|
||||
assertEquals(3, dem.elevationSample(3600, 3600), 1e-10);
|
||||
assertEquals(4, dem.elevationSample(7200, 3600), 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
private static void createHgtDemWithFileNamed(String hgtFileName) throws Exception {
|
||||
Path p = copyEmptyHgtFileAs(hgtFileName);
|
||||
try (DiscreteElevationModel d = new HgtDiscreteElevationModel(p.toFile())) {}
|
||||
}
|
||||
|
||||
private static Path copyEmptyHgtFileAs(String hgtFileName) throws IOException {
|
||||
return Files.copy(FAKE_HGT_FILE, FAKE_HGT_DIR.resolve(hgtFileName), REPLACE_EXISTING);
|
||||
}
|
||||
}
|
26
Alpano/tests/ch/epfl/alpano/dem/MemMapExample.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package ch.epfl.alpano.dem;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.FileInputStream;
|
||||
import java.nio.ShortBuffer;
|
||||
import java.nio.channels.FileChannel.MapMode;
|
||||
|
||||
public class MemMapExample {
|
||||
public static void main(String[] args)
|
||||
throws IOException {
|
||||
File f = new File("HGT"+File.separatorChar+"N46E007.hgt");
|
||||
long l = f.length();
|
||||
try (FileInputStream s = new FileInputStream(f)) {
|
||||
ShortBuffer b = s.getChannel()
|
||||
.map(MapMode.READ_ONLY, 0, l)
|
||||
.asShortBuffer();
|
||||
|
||||
for (int i = 0; i <= 5; ++i)
|
||||
System.out.println(b.get(i));
|
||||
System.out.println("-----------------");
|
||||
for (int i = 12967195; i < 12967201; ++i)
|
||||
System.out.println(b.get(i));
|
||||
}
|
||||
}
|
||||
}
|
57
Alpano/tests/ch/epfl/alpano/dem/TestWavyDEM.java
Normal file
@@ -0,0 +1,57 @@
|
||||
package ch.epfl.alpano.dem;
|
||||
|
||||
import static java.awt.image.BufferedImage.TYPE_INT_RGB;
|
||||
import static java.lang.Math.*;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import ch.epfl.alpano.*;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
public final class TestWavyDEM {
|
||||
@SuppressWarnings("resource")
|
||||
public static void main(String[] args)
|
||||
throws IOException {
|
||||
|
||||
DiscreteElevationModel dDEM1 =
|
||||
new WavyDEM(new Interval2D(new Interval1D(0, 50),
|
||||
new Interval1D(0, 100)));
|
||||
DiscreteElevationModel dDEM2 =
|
||||
new WavyDEM(new Interval2D(new Interval1D(50, 100),
|
||||
new Interval1D(0, 100)));
|
||||
DiscreteElevationModel dDEM =
|
||||
dDEM1.union(dDEM2);
|
||||
ContinuousElevationModel cDEM =
|
||||
new ContinuousElevationModel(dDEM);
|
||||
|
||||
int size = 300;
|
||||
double scale = (100d / 3600d) / (size - 1);
|
||||
BufferedImage elI =
|
||||
new BufferedImage(size, size, TYPE_INT_RGB);
|
||||
BufferedImage slI =
|
||||
new BufferedImage(size, size, TYPE_INT_RGB);
|
||||
for (int x = 0; x < size; ++x) {
|
||||
for (int y = 0; y < size; ++y) {
|
||||
GeoPoint p = new GeoPoint(toRadians(x * scale),
|
||||
toRadians(y * scale));
|
||||
double el = cDEM.elevationAt(p);
|
||||
elI.setRGB(x, y, gray(el / 1000d));
|
||||
|
||||
double sl = cDEM.slopeAt(p);
|
||||
slI.setRGB(x, y, gray(sl / (PI / 2d)));
|
||||
}
|
||||
}
|
||||
|
||||
ImageIO.write(elI, "png", new File("tests/ch/epfl/alpano/dem/elevation.png"));
|
||||
ImageIO.write(slI, "png", new File("tests/ch/epfl/alpano/dem/slope.png"));
|
||||
}
|
||||
|
||||
private static int gray(double v) {
|
||||
double clampedV = max(0, min(v, 1));
|
||||
int gray = (int) (255.9999 * clampedV);
|
||||
return (gray << 16) | (gray << 8) | gray;
|
||||
}
|
||||
}
|
28
Alpano/tests/ch/epfl/alpano/dem/WavyDEM.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package ch.epfl.alpano.dem;
|
||||
|
||||
import ch.epfl.alpano.Interval2D;
|
||||
import static java.lang.Math.PI;
|
||||
import static java.lang.Math.sin;
|
||||
import static java.lang.Math.cos;
|
||||
|
||||
final class WavyDEM implements DiscreteElevationModel {
|
||||
private final static double PERIOD = 100, HEIGHT = 1000;
|
||||
private final Interval2D extent;
|
||||
|
||||
public WavyDEM(Interval2D extent) {
|
||||
this.extent = extent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception { }
|
||||
|
||||
@Override
|
||||
public Interval2D extent() { return extent; }
|
||||
|
||||
@Override
|
||||
public double elevationSample(int x, int y) {
|
||||
double x1 = PI * 2d * x / PERIOD;
|
||||
double y1 = PI * 2d * y / PERIOD;
|
||||
return (1 + sin(x1) * cos(y1)) / 2d * HEIGHT;
|
||||
}
|
||||
}
|
BIN
Alpano/tests/ch/epfl/alpano/dem/dem.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
Alpano/tests/ch/epfl/alpano/dem/dem2.png
Normal file
After Width: | Height: | Size: 951 KiB |
BIN
Alpano/tests/ch/epfl/alpano/dem/elevation.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
Alpano/tests/ch/epfl/alpano/dem/mapView.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
Alpano/tests/ch/epfl/alpano/dem/mapzen.png
Normal file
After Width: | Height: | Size: 446 KiB |
BIN
Alpano/tests/ch/epfl/alpano/dem/mapzenSlope.png
Normal file
After Width: | Height: | Size: 252 KiB |
BIN
Alpano/tests/ch/epfl/alpano/dem/profile.png
Normal file
After Width: | Height: | Size: 800 B |
BIN
Alpano/tests/ch/epfl/alpano/dem/slope.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
Alpano/tests/ch/epfl/alpano/dem/testImage.png
Normal file
After Width: | Height: | Size: 354 KiB |
31
Alpano/tests/ch/epfl/alpano/gui/BeansUse.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package ch.epfl.alpano.gui;
|
||||
import static ch.epfl.alpano.gui.PredefinedPanoramas.*;
|
||||
|
||||
import ch.epfl.alpano.gui.PanoramaParametersBean;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public final class BeansUse extends Application {
|
||||
public static void main(String[] args) {
|
||||
launch(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
PanoramaParametersBean bean =
|
||||
new PanoramaParametersBean(NIESEN.get());
|
||||
ObjectProperty<Integer> prop =
|
||||
bean.ObserverLatitudeProperty();
|
||||
|
||||
prop.addListener((o, oV, nV) ->
|
||||
System.out.printf(" %d -> %d (%s)%n", oV, nV, o));
|
||||
System.out.println("set to 1");
|
||||
prop.set(1);
|
||||
System.out.println("set to 2");
|
||||
prop.set(2);
|
||||
|
||||
Platform.exit();
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
package ch.epfl.alpano.gui;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class FixedPointStringConverterTest {
|
||||
|
||||
@Test
|
||||
public void testFixedPointStringConverter() {
|
||||
//fail("Not yet implemented");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromStringString() {
|
||||
FixedPointStringConverter f = new FixedPointStringConverter(4);
|
||||
assertEquals(123457, (int)f.fromString("12.3456789"));
|
||||
FixedPointStringConverter f1 = new FixedPointStringConverter(2);
|
||||
assertEquals("1011", f1.toString(101100));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToStringInteger() {
|
||||
FixedPointStringConverter f = new FixedPointStringConverter(1);
|
||||
assertEquals("67.8", f.toString(678));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
package ch.epfl.alpano.gui;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
|
||||
public class LabeledListStringConverterTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void testLabeledListStringConverter() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromStringString() {
|
||||
LabeledListStringConverter c = new LabeledListStringConverter("none","2x","4x");
|
||||
System.out.println(c.fromString("2x"));
|
||||
//assertEquals(1,c.fromString("2x"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToStringInteger() {
|
||||
LabeledListStringConverter c = new LabeledListStringConverter("none","2x","4x");
|
||||
|
||||
assertEquals("none",c.toString(0));
|
||||
}
|
||||
|
||||
}
|
50
Alpano/tests/ch/epfl/alpano/gui/LabelizerTest.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package ch.epfl.alpano.gui;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ch.epfl.alpano.dem.ContinuousElevationModel;
|
||||
import ch.epfl.alpano.dem.HgtDiscreteElevationModel;
|
||||
import ch.epfl.alpano.summit.GazetteerParser;
|
||||
import ch.epfl.alpano.summit.Summit;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
public class LabelizerTest {
|
||||
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testLabels() {
|
||||
|
||||
try {
|
||||
|
||||
|
||||
List<Summit> listOfSummit = GazetteerParser.readSummitsFrom(new File("HGT/alps.txt"));
|
||||
|
||||
HgtDiscreteElevationModel dDem = new HgtDiscreteElevationModel(new File ("HGT/N46E007.hgt"));
|
||||
ContinuousElevationModel cDem = new ContinuousElevationModel(dDem);
|
||||
Labelizer l = new Labelizer(cDem, listOfSummit);
|
||||
List<Node> n= l.labels(PredefinedPanoramas.NIESEN.get().panoramaComputeParameters());
|
||||
int count =0;
|
||||
for (Node node : n){
|
||||
System.out.println(node);
|
||||
if (node instanceof Text){
|
||||
++count;
|
||||
//System.out.println("node");
|
||||
System.out.println(node.toString());
|
||||
}
|
||||
}
|
||||
System.out.println(count);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
BIN
Alpano/tests/ch/epfl/alpano/niesen-profile.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
Alpano/tests/ch/epfl/alpano/niesen-profileP.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
Alpano/tests/ch/epfl/alpano/niesen.png
Normal file
After Width: | Height: | Size: 9.4 KiB |
BIN
Alpano/tests/ch/epfl/alpano/np.png
Normal file
After Width: | Height: | Size: 9.4 KiB |
BIN
Alpano/tests/ch/epfl/alpano/out.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
Alpano/tests/ch/epfl/alpano/out2.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
41
Alpano/tests/ch/epfl/alpano/sigcheck/SignatureChecks_02.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package ch.epfl.alpano.sigcheck;
|
||||
|
||||
import ch.epfl.alpano.GeoPoint;
|
||||
import ch.epfl.alpano.Interval1D;
|
||||
import ch.epfl.alpano.Interval2D;
|
||||
|
||||
final class SignatureChecks_02 {
|
||||
private SignatureChecks_02() {}
|
||||
|
||||
String checkGeoPoint() {
|
||||
double lon = 0, lat = 0;
|
||||
GeoPoint p = new GeoPoint(lon, lat);
|
||||
lon += p.longitude() + p.latitude();
|
||||
double d = p.distanceTo(p);
|
||||
double a = p.azimuthTo(p);
|
||||
return String.valueOf(d) + a;
|
||||
}
|
||||
|
||||
String checkInterval1D() {
|
||||
int a = 0;
|
||||
Interval1D i = new Interval1D(a, a);
|
||||
a = i.includedFrom() + i.includedTo() + i.size() + i.sizeOfIntersectionWith(i);
|
||||
boolean b = i.contains(a)
|
||||
| i.isUnionableWith(i);
|
||||
i = i.union(i.boundingUnion(i));
|
||||
return i.toString() + b;
|
||||
}
|
||||
|
||||
String checkInterval2D() {
|
||||
int a = 0;
|
||||
Interval1D i1 = null;
|
||||
Interval2D i2 = new Interval2D(i1, i1);
|
||||
i1 = i2.iX();
|
||||
i1 = i2.iY();
|
||||
a = i2.size() + i2.sizeOfIntersectionWith(i2);
|
||||
boolean b = i2.contains(a, a)
|
||||
| i2.isUnionableWith(i2);
|
||||
i2 = i2.union(i2.boundingUnion(i2));
|
||||
return i2.toString() + b;
|
||||
}
|
||||
}
|
29
Alpano/tests/ch/epfl/alpano/sigcheck/SignatureChecks_03.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package ch.epfl.alpano.sigcheck;
|
||||
|
||||
import ch.epfl.alpano.GeoPoint;
|
||||
import ch.epfl.alpano.Interval2D;
|
||||
import ch.epfl.alpano.dem.ContinuousElevationModel;
|
||||
import ch.epfl.alpano.dem.DiscreteElevationModel;
|
||||
|
||||
final class SignatureChecks_03 {
|
||||
private SignatureChecks_03() {}
|
||||
|
||||
String checkDiscElevationModel(DiscreteElevationModel d) throws Exception {
|
||||
double a = DiscreteElevationModel.SAMPLES_PER_DEGREE * DiscreteElevationModel.SAMPLES_PER_RADIAN;
|
||||
a = DiscreteElevationModel.sampleIndex(a);
|
||||
Interval2D e = d.extent();
|
||||
int v = 0;
|
||||
a = d.elevationSample(v, v);
|
||||
d = d.union(d);
|
||||
d.close();
|
||||
return d.toString() + e;
|
||||
}
|
||||
|
||||
String checkContElevationModel() {
|
||||
DiscreteElevationModel md = null;
|
||||
ContinuousElevationModel m = new ContinuousElevationModel(md);
|
||||
GeoPoint p = null;
|
||||
double e = m.elevationAt(p) + m.slopeAt(p);
|
||||
return String.valueOf(e);
|
||||
}
|
||||
}
|
30
Alpano/tests/ch/epfl/alpano/sigcheck/SignatureChecks_04.java
Normal file
@@ -0,0 +1,30 @@
|
||||
package ch.epfl.alpano.sigcheck;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import ch.epfl.alpano.GeoPoint;
|
||||
import ch.epfl.alpano.dem.ContinuousElevationModel;
|
||||
import ch.epfl.alpano.dem.DiscreteElevationModel;
|
||||
import ch.epfl.alpano.dem.ElevationProfile;
|
||||
import ch.epfl.alpano.dem.HgtDiscreteElevationModel;
|
||||
|
||||
final class SignatureChecks_04 {
|
||||
private SignatureChecks_04() {}
|
||||
|
||||
void checkHgtDiscreteElevationModel() {
|
||||
File f = null;
|
||||
DiscreteElevationModel m = new HgtDiscreteElevationModel(f);
|
||||
System.out.println(m);
|
||||
}
|
||||
|
||||
void checkElevationProfile() {
|
||||
ContinuousElevationModel dem = null;
|
||||
GeoPoint o = null;
|
||||
double d = 0;
|
||||
|
||||
ElevationProfile p = new ElevationProfile(dem, o, d, d);
|
||||
d = p.elevationAt(d);
|
||||
o = p.positionAt(d);
|
||||
d = p.slopeAt(d);
|
||||
}
|
||||
}
|
46
Alpano/tests/ch/epfl/alpano/sigcheck/SignatureChecks_05.java
Normal file
@@ -0,0 +1,46 @@
|
||||
package ch.epfl.alpano.sigcheck;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import ch.epfl.alpano.GeoPoint;
|
||||
import ch.epfl.alpano.PanoramaParameters;
|
||||
import ch.epfl.alpano.summit.GazetteerParser;
|
||||
import ch.epfl.alpano.summit.Summit;
|
||||
|
||||
final class SignatureChecks_05 {
|
||||
private SignatureChecks_05() {}
|
||||
|
||||
void checkSummit() {
|
||||
GeoPoint p = null;
|
||||
int e = 0;
|
||||
Summit s = new Summit("", p, e);
|
||||
p = s.position();
|
||||
e = s.elevation();
|
||||
System.out.println(s.name());
|
||||
}
|
||||
|
||||
void checkGazetteerParser() throws IOException {
|
||||
File f = null;
|
||||
List<Summit> s = GazetteerParser.readSummitsFrom(f);
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
void checkPanoramaParameters() {
|
||||
GeoPoint p = null;
|
||||
int i = 0;
|
||||
double d = 0d;
|
||||
PanoramaParameters pp = new PanoramaParameters(p, i, d, d, i, i, i);
|
||||
p = pp.observerPosition();
|
||||
i = pp.observerElevation();
|
||||
d = pp.centerAzimuth();
|
||||
d = pp.horizontalFieldOfView();
|
||||
d = pp.verticalFieldOfView();
|
||||
i = pp.width();
|
||||
i = pp.height();
|
||||
i = pp.maxDistance();
|
||||
d = pp.xForAzimuth(pp.azimuthForX(d));
|
||||
d = pp.yForAltitude(pp.altitudeForY(d));
|
||||
}
|
||||
}
|
49
Alpano/tests/ch/epfl/alpano/sigcheck/SignatureChecks_06.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package ch.epfl.alpano.sigcheck;
|
||||
|
||||
import java.util.function.DoubleUnaryOperator;
|
||||
|
||||
import ch.epfl.alpano.Panorama;
|
||||
import ch.epfl.alpano.PanoramaComputer;
|
||||
import ch.epfl.alpano.PanoramaParameters;
|
||||
import ch.epfl.alpano.dem.ContinuousElevationModel;
|
||||
import ch.epfl.alpano.dem.ElevationProfile;
|
||||
|
||||
final class SignatureChecks_06 {
|
||||
private SignatureChecks_06() {}
|
||||
|
||||
void checkPanorama(Panorama p) {
|
||||
PanoramaParameters pp = p.parameters();
|
||||
int x = 0;
|
||||
float d = p.distanceAt(x, x);
|
||||
d = p.distanceAt(x, x, d);
|
||||
d = p.longitudeAt(x, x);
|
||||
d = p.latitudeAt(x, x);
|
||||
d = p.elevationAt(x, x);
|
||||
d = p.slopeAt(x, x);
|
||||
checkPanoramaBuilder(pp);
|
||||
}
|
||||
|
||||
void checkPanoramaBuilder(PanoramaParameters pp) {
|
||||
Panorama.Builder b = new Panorama.Builder(pp);
|
||||
int x = 0;
|
||||
float d = 0;
|
||||
b.setDistanceAt(x, x, d);
|
||||
b.setLongitudeAt(x, x, d);
|
||||
b.setLatitudeAt(x, x, d);
|
||||
b.setElevationAt(x, x, d);
|
||||
b.setSlopeAt(x, x, d);
|
||||
Panorama p = b.build();
|
||||
checkPanorama(p);
|
||||
}
|
||||
|
||||
void checkPanoramaComputer(PanoramaParameters pp) {
|
||||
ContinuousElevationModel d = null;
|
||||
PanoramaComputer pc = new PanoramaComputer(d);
|
||||
Panorama p = pc.computePanorama(pp);
|
||||
checkPanorama(p);
|
||||
double y = 0;
|
||||
ElevationProfile pr = null;
|
||||
DoubleUnaryOperator o = PanoramaComputer.rayToGroundDistance(pr, y, y);
|
||||
System.out.println(o);
|
||||
}
|
||||
}
|
12
Alpano/tests/ch/epfl/alpano/sigcheck/SignatureChecks_11.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package ch.epfl.alpano.sigcheck;
|
||||
|
||||
import ch.epfl.alpano.gui.Alpano;
|
||||
|
||||
final class SignatureChecks_11 {
|
||||
private SignatureChecks_11() {}
|
||||
|
||||
void checkAlpano() {
|
||||
String[] args = null;
|
||||
Alpano.main(args);
|
||||
}
|
||||
}
|
136
Alpano/tests/ch/epfl/alpano/summit/GazetteerParserTest.java
Normal file
@@ -0,0 +1,136 @@
|
||||
package ch.epfl.alpano.summit;
|
||||
|
||||
import static ch.epfl.alpano.summit.GazetteerParser.readSummitsFrom;
|
||||
import static java.lang.Math.toDegrees;
|
||||
import static java.lang.Math.toRadians;
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ch.epfl.alpano.GeoPoint;
|
||||
|
||||
public class GazetteerParserTest {
|
||||
@Test(expected = IOException.class)
|
||||
public void parserFailsOnNonExistantFile() throws IOException {
|
||||
readSummitsFrom(new File("/ /d:/ééé"));
|
||||
}
|
||||
|
||||
@Test(expected = IOException.class)
|
||||
public void parserFailsOnGarbageLine() throws IOException {
|
||||
readSummitsFrom(tempFileWithLines("blabla"));
|
||||
}
|
||||
|
||||
@Test(expected = IOException.class)
|
||||
public void parserFailsOnInvalidLongitude() throws IOException {
|
||||
String l = " 7:25:1x 45:08:25 1325 R0 E07 BA MONTE CURT";
|
||||
readSummitsFrom(tempFileWithLines(l));
|
||||
}
|
||||
|
||||
@Test(expected = IOException.class)
|
||||
public void parserFailsOnInvalidLatitude() throws IOException {
|
||||
String l = " 7:25:12 45:08:2_ 1325 R0 E07 BA MONTE CURT";
|
||||
readSummitsFrom(tempFileWithLines(l));
|
||||
}
|
||||
|
||||
@Test(expected = IOException.class)
|
||||
public void parserFailsOnInvalidElevation() throws IOException {
|
||||
String l = " 7:25:12 45:08:25 leet R0 E07 BA MONTE CURT";
|
||||
readSummitsFrom(tempFileWithLines(l));
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void summitListIsUnmodifiable() throws IOException {
|
||||
String l = " 7:01:02 46:32:56 2002 H1 B01 D7 LE MOLESON";
|
||||
readSummitsFrom(tempFileWithLines(l)).clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parserWorksOnValidFile() throws IOException {
|
||||
List<Summit> summits = Arrays.asList(
|
||||
new Summit("A MONT UN", hmsPoint(7, 30, 00, 15, 16, 17), 30),
|
||||
new Summit("B MONT ZWEI", hmsPoint(6, 12, 34, 1, 23, 45), 10),
|
||||
new Summit("C MONTE TRE", hmsPoint(1, 33, 33, 15, 66, 66), 1000),
|
||||
new Summit("D MONT AU NOM TRES LONG", hmsPoint(5, 00, 00, 5, 00, 00), 8000));
|
||||
String[] formattedSummits = new String[summits.size()];
|
||||
int i = 0;
|
||||
for (Summit s: summits)
|
||||
formattedSummits[i++] = formatSummit(s);
|
||||
File f = tempFileWithLines(formattedSummits);
|
||||
List<Summit> readSummits = new ArrayList<>(readSummitsFrom(f));
|
||||
assertEquals(summits.size(), readSummits.size());
|
||||
|
||||
readSummits.sort(Comparator.comparing(Summit::name));
|
||||
Iterator<Summit> expectedIt = summits.iterator();
|
||||
Iterator<Summit> actualIt = readSummits.iterator();
|
||||
while (expectedIt.hasNext()) {
|
||||
Summit expected = expectedIt.next();
|
||||
Summit actual = actualIt.next();
|
||||
assertEquals(expected.name(), actual.name());
|
||||
assertEquals(expected.elevation(), actual.elevation());
|
||||
assertEquals(
|
||||
expected.position().longitude(),
|
||||
actual.position().longitude(),
|
||||
toRadians(1d / 3600d));
|
||||
assertEquals(
|
||||
expected.position().latitude(),
|
||||
actual.position().latitude(),
|
||||
toRadians(1d / 3600d));
|
||||
}
|
||||
}
|
||||
|
||||
private String formatSummit(Summit s) {
|
||||
double lon = s.position().longitude();
|
||||
double lat = s.position().latitude();
|
||||
return String.format("%3d:%02d:%02d %2d:%02d:%02d %5d R0 E07 BA %s",
|
||||
h(lon), m(lon), s(lon), h(lat), m(lat), s(lat), s.elevation(), s.name());
|
||||
}
|
||||
|
||||
private static GeoPoint hmsPoint(
|
||||
int hLon, int mLon, int sLon,
|
||||
int hLat, int mLat, int sLat) {
|
||||
return new GeoPoint(hmsToRad(hLon, mLon, sLon), hmsToRad(hLat, mLat, sLat));
|
||||
}
|
||||
|
||||
private static double hmsToRad(int h, int m, int s) {
|
||||
return toRadians(h + (m / 60d) + (s / 3600d));
|
||||
}
|
||||
|
||||
private static int h(double d) {
|
||||
return (int)toDegrees(d);
|
||||
}
|
||||
|
||||
private static int m(double d) {
|
||||
return (int)(toDegrees(d) * 60d) % 60;
|
||||
}
|
||||
|
||||
private static int s(double d) {
|
||||
return (int)(toDegrees(d) * 3600d) % 60;
|
||||
}
|
||||
|
||||
private static File tempFileWithLines(String... lines) throws IOException {
|
||||
File f = Files.createTempFile("summits", ".txt").toFile();
|
||||
f.deleteOnExit();
|
||||
try (BufferedWriter b = new BufferedWriter(
|
||||
new OutputStreamWriter(
|
||||
new FileOutputStream(f), US_ASCII))) {
|
||||
for (String l: lines) {
|
||||
b.write(l);
|
||||
b.newLine();
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
}
|
136
Alpano/tests/ch/epfl/alpano/summit/GazetterParserTestP.java
Normal file
@@ -0,0 +1,136 @@
|
||||
package ch.epfl.alpano.summit;
|
||||
|
||||
import static ch.epfl.alpano.summit.GazetteerParser.readSummitsFrom;
|
||||
import static java.lang.Math.toDegrees;
|
||||
import static java.lang.Math.toRadians;
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ch.epfl.alpano.GeoPoint;
|
||||
|
||||
public class GazetterParserTestP {
|
||||
@Test(expected = IOException.class)
|
||||
public void parserFailsOnNonExistantFile() throws IOException {
|
||||
readSummitsFrom(new File("/ /d:/ééé"));
|
||||
}
|
||||
|
||||
@Test(expected = IOException.class)
|
||||
public void parserFailsOnGarbageLine() throws IOException {
|
||||
readSummitsFrom(tempFileWithLines("blabla"));
|
||||
}
|
||||
|
||||
@Test(expected = IOException.class)
|
||||
public void parserFailsOnInvalidLongitude() throws IOException {
|
||||
String l = " 7:25:1x 45:08:25 1325 R0 E07 BA MONTE CURT";
|
||||
readSummitsFrom(tempFileWithLines(l));
|
||||
}
|
||||
|
||||
@Test(expected = IOException.class)
|
||||
public void parserFailsOnInvalidLatitude() throws IOException {
|
||||
String l = " 7:25:12 45:08:2_ 1325 R0 E07 BA MONTE CURT";
|
||||
readSummitsFrom(tempFileWithLines(l));
|
||||
}
|
||||
|
||||
@Test(expected = IOException.class)
|
||||
public void parserFailsOnInvalidElevation() throws IOException {
|
||||
String l = " 7:25:12 45:08:25 leet R0 E07 BA MONTE CURT";
|
||||
readSummitsFrom(tempFileWithLines(l));
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void summitListIsUnmodifiable() throws IOException {
|
||||
String l = " 7:01:02 46:32:56 2002 H1 B01 D7 LE MOLESON";
|
||||
readSummitsFrom(tempFileWithLines(l)).clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parserWorksOnValidFile() throws IOException {
|
||||
List<Summit> summits = Arrays.asList(
|
||||
new Summit("A MONT UN", hmsPoint(7, 30, 00, 15, 16, 17), 30),
|
||||
new Summit("B MONT ZWEI", hmsPoint(6, 12, 34, 1, 23, 45), 10),
|
||||
new Summit("C MONTE TRE", hmsPoint(1, 33, 33, 15, 66, 66), 1000),
|
||||
new Summit("D MONT AU NOM TRES LONG", hmsPoint(5, 00, 00, 5, 00, 00), 8000));
|
||||
String[] formattedSummits = new String[summits.size()];
|
||||
int i = 0;
|
||||
for (Summit s: summits)
|
||||
formattedSummits[i++] = formatSummit(s);
|
||||
File f = tempFileWithLines(formattedSummits);
|
||||
List<Summit> readSummits = new ArrayList<>(readSummitsFrom(f));
|
||||
assertEquals(summits.size(), readSummits.size());
|
||||
|
||||
readSummits.sort(Comparator.comparing(Summit::name));
|
||||
Iterator<Summit> expectedIt = summits.iterator();
|
||||
Iterator<Summit> actualIt = readSummits.iterator();
|
||||
while (expectedIt.hasNext()) {
|
||||
Summit expected = expectedIt.next();
|
||||
Summit actual = actualIt.next();
|
||||
assertEquals(expected.name(), actual.name());
|
||||
assertEquals(expected.elevation(), actual.elevation());
|
||||
assertEquals(
|
||||
expected.position().longitude(),
|
||||
actual.position().longitude(),
|
||||
toRadians(1d / 3600d));
|
||||
assertEquals(
|
||||
expected.position().latitude(),
|
||||
actual.position().latitude(),
|
||||
toRadians(1d / 3600d));
|
||||
}
|
||||
}
|
||||
|
||||
private String formatSummit(Summit s) {
|
||||
double lon = s.position().longitude();
|
||||
double lat = s.position().latitude();
|
||||
return String.format("%3d:%02d:%02d %2d:%02d:%02d %5d R0 E07 BA %s",
|
||||
h(lon), m(lon), s(lon), h(lat), m(lat), s(lat), s.elevation(), s.name());
|
||||
}
|
||||
|
||||
private static GeoPoint hmsPoint(
|
||||
int hLon, int mLon, int sLon,
|
||||
int hLat, int mLat, int sLat) {
|
||||
return new GeoPoint(hmsToRad(hLon, mLon, sLon), hmsToRad(hLat, mLat, sLat));
|
||||
}
|
||||
|
||||
private static double hmsToRad(int h, int m, int s) {
|
||||
return toRadians(h + (m / 60d) + (s / 3600d));
|
||||
}
|
||||
|
||||
private static int h(double d) {
|
||||
return (int)toDegrees(d);
|
||||
}
|
||||
|
||||
private static int m(double d) {
|
||||
return (int)(toDegrees(d) * 60d) % 60;
|
||||
}
|
||||
|
||||
private static int s(double d) {
|
||||
return (int)(toDegrees(d) * 3600d) % 60;
|
||||
}
|
||||
|
||||
private static File tempFileWithLines(String... lines) throws IOException {
|
||||
File f = Files.createTempFile("summits", ".txt").toFile();
|
||||
f.deleteOnExit();
|
||||
try (BufferedWriter b = new BufferedWriter(
|
||||
new OutputStreamWriter(
|
||||
new FileOutputStream(f), US_ASCII))) {
|
||||
for (String l: lines) {
|
||||
b.write(l);
|
||||
b.newLine();
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
}
|
41
Alpano/tests/ch/epfl/alpano/summit/SummitTestP.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package ch.epfl.alpano.summit;
|
||||
|
||||
import static java.lang.Math.toRadians;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ch.epfl.alpano.GeoPoint;
|
||||
|
||||
public class SummitTestP {
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void constructorFailsWithNullName() {
|
||||
new Summit(null, new GeoPoint(0, 0), 1);
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void constructorFailsWithNullPosition() {
|
||||
new Summit("sommet", null, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nameReturnsName() {
|
||||
String n = "sommet";
|
||||
Summit s = new Summit(n, new GeoPoint(0,0), 1);
|
||||
assertEquals(n, s.name());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void positionReturnsPosition() {
|
||||
GeoPoint p = new GeoPoint(toRadians(3), toRadians(5));
|
||||
Summit s = new Summit("sommet", p, 1);
|
||||
assertEquals(p, s.position());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void elevationReturnsElevation() {
|
||||
int e = 1234;
|
||||
Summit s = new Summit("sommet", new GeoPoint(0, 0), e);
|
||||
assertEquals(e, s.elevation());
|
||||
}
|
||||
}
|
BIN
Alpano/tests/ch/epfl/alpano/zermatpzen.png
Normal file
After Width: | Height: | Size: 78 KiB |
7
Alpano/tests/ch/epfl/test/ObjectTest.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package ch.epfl.test;
|
||||
|
||||
public interface ObjectTest {
|
||||
public static boolean hashCodeIsCompatibleWithEquals(Object o1, Object o2) {
|
||||
return ! o1.equals(o2) || o1.hashCode() == o2.hashCode();
|
||||
}
|
||||
}
|
14
Alpano/tests/ch/epfl/test/TestRandomizer.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package ch.epfl.test;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public interface TestRandomizer {
|
||||
// Fix random seed to guarantee reproducibility.
|
||||
public final static long SEED = 2017;
|
||||
|
||||
public final static int RANDOM_ITERATIONS = 500;
|
||||
|
||||
public static Random newRandom() {
|
||||
return new Random(SEED);
|
||||
}
|
||||
}
|