ProjectionWgs84 implements GeographicProjection { @Override public boolean intersect(Globe globe, Line line, Vec3 result) { if (globe == null) { throw new IllegalArgumentException( Logger.logMessage(Logger.ERROR, "ProjectionWgs84", "cartesianToGeographic", "missingGlobe")); } if (line == null) { throw new IllegalArgumentException( Logger.logMessage(Logger.ERROR, "ProjectionWgs84", "intersect", "missingLine")); } if (result == null) { throw new IllegalArgumentException( Logger.logMessage(Logger.ERROR, "ProjectionWgs84", "intersect", "missingResult")); } double vx = line.direction.x; double vy = line.direction.y; double vz = line.direction.z; double sx = line.origin.x; double sy = line.origin.y; double sz = line.origin.z; double eqr = globe.getEquatorialRadius(); double eqr2 = eqr * eqr; double m = eqr / globe.getPolarRadius(); double m2 = m * m; double a = vx * vx + m2 * vy * vy + vz * vz; double b = 2 * (sx * vx + m2 * sy * vy + sz * vz); double c = sx * sx + m2 * sy * sy + sz * sz - eqr2; double d = b * b - 4 * a * c; if (d < 0) { return false; } double t = (-b - Math.sqrt(d)) / (2 * a); if (t > 0) { result.x = sx + vx * t; result.y = sy + vy * t; result.z = sz + vz * t; return true; } t = (-b + Math.sqrt(d)) / (2 * a); if (t > 0) { result.x = sx + vx * t; result.y = sy + vy * t; result.z = sz + vz * t; return true; } return false; } ProjectionWgs84(); @Override String getDisplayName(); @Override Vec3 geographicToCartesian(Globe globe, double latitude, double longitude, double altitude, Vec3 result); @Override Vec3 geographicToCartesianNormal(Globe globe, double latitude, double longitude, Vec3 result); @Override Matrix4 geographicToCartesianTransform(Globe globe, double latitude, double longitude, double altitude, Matrix4 result); @Override float[] geographicToCartesianGrid(Globe globe, Sector sector, int numLat, int numLon, float[] height, float verticalExaggeration,
                                             Vec3 origin, float[] result, int offset, int rowStride); float[] geographicToCartesianBorder(Globe globe, Sector sector, int numLat, int numLon, float height,
                                               Vec3 origin, float[] result); @SuppressWarnings({"UnnecessaryLocalVariable", "SuspiciousNameCombination"}) @Override Position cartesianToGeographic(Globe globe, double x, double y, double z, Position result); @Override Matrix4 cartesianToLocalTransform(Globe globe, double x, double y, double z, Matrix4 result); @Override boolean intersect(Globe globe, Line line, Vec3 result);  }
@Test public void testEmpBackwardInstance() throws Exception { ProjectionWgs84 wgs84 = new ProjectionWgs84(); Line ray = new Line(new Vec3(990474.8037403631, 3007310.9566306924, 5583923.602748461), new Vec3(-0.1741204769506282, 0.9711294099374702, -0.16306357245254538)); boolean intersection = wgs84.intersect(this.globe, ray, new Vec3()); assertFalse("EMP backward intersection", intersection); }
@Test public void testSimpleBackwardsIntersection() throws Exception { ProjectionWgs84 wgs84 = new ProjectionWgs84(); Globe mockedGlobe = PowerMockito.mock(Globe.class); PowerMockito.when(mockedGlobe.getEquatorialRadius()).thenReturn(1.0); PowerMockito.when(mockedGlobe.getPolarRadius()).thenReturn(1.0); Line ray = new Line(new Vec3(0.8, 0.8, 0.0), new Vec3(0.0, 1.0, 0.0)); boolean intersection = wgs84.intersect(mockedGlobe, ray, new Vec3()); assertFalse("simple backwards intersection", intersection); }
@Test public void testSimpleIntersection() throws Exception { ProjectionWgs84 wgs84 = new ProjectionWgs84(); Globe mockedGlobe = PowerMockito.mock(Globe.class); PowerMockito.when(mockedGlobe.getEquatorialRadius()).thenReturn(1.0); PowerMockito.when(mockedGlobe.getPolarRadius()).thenReturn(1.0); Line ray = new Line(new Vec3(0.8, 0.8, 0.0), new Vec3(0.0, -1.0, 0.0)); boolean intersection = wgs84.intersect(mockedGlobe, ray, new Vec3()); assertTrue("simple intersection", intersection); }
@Test public void testSimpleTwoIntersection() throws Exception { ProjectionWgs84 wgs84 = new ProjectionWgs84(); Globe mockedGlobe = PowerMockito.mock(Globe.class); PowerMockito.when(mockedGlobe.getEquatorialRadius()).thenReturn(1.0); PowerMockito.when(mockedGlobe.getPolarRadius()).thenReturn(1.0); Line ray = new Line(new Vec3(-1.0, 2.0, 0.0), new Vec3(1.0, -1.0, 0.0).normalize()); Vec3 result = new Vec3(); double errorThreshold = 1e-9; boolean intersection = wgs84.intersect(mockedGlobe, ray, result); assertTrue("simple intersection", intersection); assertEquals("nearest calculated intersection x", 0.0, result.x, errorThreshold); assertEquals("nearest calculated intersection y", 1.0, result.y, errorThreshold); }
@Test public void testSimpleTwoIntersectionInternal() throws Exception { ProjectionWgs84 wgs84 = new ProjectionWgs84(); Globe mockedGlobe = PowerMockito.mock(Globe.class); PowerMockito.when(mockedGlobe.getEquatorialRadius()).thenReturn(1.0); PowerMockito.when(mockedGlobe.getPolarRadius()).thenReturn(1.0); Line ray = new Line(new Vec3(-0.8, 0, 0.0), new Vec3(1.0, 0.0, 0.0).normalize()); Vec3 result = new Vec3(); double errorThreshold = 1e-9; boolean intersection = wgs84.intersect(mockedGlobe, ray, result); assertTrue("simple internal intersection", intersection); assertEquals("forward calculated intersection x", 1.0, result.x, errorThreshold); assertEquals("forward calculated intersection y", 0.0, result.y, errorThreshold); }