From 57af743013492eff8e40e087d0cc7aa2e0103d06 Mon Sep 17 00:00:00 2001 From: Leon Schmidtchen Date: Wed, 24 Nov 2021 15:00:12 +0100 Subject: [PATCH] Added AbstractCoordinate class --- .../wahlzeit/model/AbstractCoordinate.java | 65 ++++++++++++++++++ .../wahlzeit/model/CartesianCoordinate.java | 66 ++---------------- .../java/org/wahlzeit/model/Coordinate.java | 4 +- .../org/wahlzeit/model/SphericCoordinate.java | 68 ++----------------- .../org/wahlzeit/model/CoordinateTest.java | 47 +++++++++++-- 5 files changed, 120 insertions(+), 130 deletions(-) create mode 100644 src/main/java/org/wahlzeit/model/AbstractCoordinate.java diff --git a/src/main/java/org/wahlzeit/model/AbstractCoordinate.java b/src/main/java/org/wahlzeit/model/AbstractCoordinate.java new file mode 100644 index 000000000..5dc7f4d65 --- /dev/null +++ b/src/main/java/org/wahlzeit/model/AbstractCoordinate.java @@ -0,0 +1,65 @@ +/* + * Extension after Fork for FAU course ADAP + * Leon Schmidtchen + */ + +package org.wahlzeit.model; + +public abstract class AbstractCoordinate implements Coordinate { + + /** + * The Location object currently associated with this Coordinate. + */ + private Location location; + + /** + * @methodtype get + */ + public Location getLocation() { + return location; + } + + /** + * @methodtype set (bi-directional with private attribute Location.coordinate) + */ + protected Coordinate setLocation(Location loc) { + if (loc == null) { + System.err.println("Won't set location attribute of coordinate to null"); + } else { + this.location = loc; + loc.coordinate = this; + } + + return this; + } + + public double getCentralAngle(Coordinate c) { + double ro1 = this.asSphericCoordinate().getPhi(); + double lam1 = this.asSphericCoordinate().getTheta(); + double ro2 = c.asSphericCoordinate().getPhi(); + double lam2 = c.asSphericCoordinate().getTheta(); + + double deltaX = Math.cos(ro2) * Math.cos(lam2) - Math.cos(ro1) * Math.cos(lam1); + double deltaY = Math.cos(ro2) * Math.sin(lam2) - Math.cos(ro1) * Math.sin(lam1); + double deltaZ = Math.sin(ro2) - Math.sin(ro1); + + double C = Math.sqrt(deltaX*deltaX + deltaY*deltaY + deltaZ*deltaZ); + + return 2 * Math.asin(C / 2); + } + + @Override + public boolean isEqual(Coordinate c) { + if (this == c) + return true; + if (c == null) + return false; + + return this.isWithinDistance(c, 0.001); + } + + private boolean isWithinDistance(Coordinate c, double epsilon) { + return (this.getCartesianDistance(c) < epsilon); + } + +} diff --git a/src/main/java/org/wahlzeit/model/CartesianCoordinate.java b/src/main/java/org/wahlzeit/model/CartesianCoordinate.java index 6b537d622..f389d51d7 100644 --- a/src/main/java/org/wahlzeit/model/CartesianCoordinate.java +++ b/src/main/java/org/wahlzeit/model/CartesianCoordinate.java @@ -9,15 +9,10 @@ /* * Local plain class to store 3D Cartesian Coordinate values. */ -class CartesianCoordinate implements Coordinate { +public class CartesianCoordinate extends AbstractCoordinate { private double x, y, z; - /** - * The Location object currently associated with this Coordinate. - */ - private Location location; - public CartesianCoordinate(double x, double y, double z) { this.x = x; this.y = y; @@ -29,9 +24,7 @@ public CartesianCoordinate(double x, double y, double z, Location l) { this.y = y; this.z = z; - if (l != null) { - this.setLocation(l); - } + this.setLocation(l); } /** @@ -55,23 +48,6 @@ public double getZ() { return z; } - /** - * @methodtype get - */ - public Location getLocation() { - return location; - } - - /** - * @methodtype set (bi-directional with private attribute Location.coordinate) - */ - protected Coordinate setLocation(Location loc) { - this.location = loc; - loc.coordinate = this; - - return this; - } - // Cartesian distance private double getDistance(CartesianCoordinate other) { if (other == null) return Double.NaN; @@ -115,44 +91,14 @@ public SphericCoordinate asSphericCoordinate() { return SphericCoordinate.fromCartesian(this); } - @Override - public double getCentralAngle(Coordinate c) { - double ro1 = this.asSphericCoordinate().getPhi(); - double lam1 = this.asSphericCoordinate().getTheta(); - double ro2 = c.asSphericCoordinate().getPhi(); - double lam2 = c.asSphericCoordinate().getTheta(); - - double deltaX = Math.cos(ro2) * Math.cos(lam2) - Math.cos(ro1) * Math.cos(lam1); - double deltaY = Math.cos(ro2) * Math.sin(lam2) - Math.cos(ro1) * Math.sin(lam1); - double deltaZ = Math.sin(ro2) - Math.sin(ro1); - - double C = Math.sqrt(deltaX*deltaX + deltaY*deltaY + deltaZ*deltaZ); - - return 2 * Math.asin(C / 2); - } - - @Override - public boolean isEqual(Coordinate c) { - if (this == c) - return true; - if (c == null) - return false; - - return this.isWithinDistance(c, 0.001); - } - - private boolean isWithinDistance(Coordinate c, double epsilon) { - return (this.getCartesianDistance(c) < epsilon); - } - /** * Custom Java-Object methods for hashCode, equals and toString */ @Override public int hashCode() { int result = 0; - if (location != null) { - result += location.hashCode(); + if (getLocation() != null) { + result += getLocation().hashCode(); } result += 2 * Double.valueOf(x).hashCode(); result -= 3 * Double.valueOf(y).hashCode(); @@ -179,8 +125,8 @@ public boolean equals(Object obj) { return false; if (z != other.z) return false; - if (location != null && other.location != null && - !location.equals(other.location)) + if (getLocation() != null && other.getLocation() != null && + !getLocation().equals(other.getLocation())) return false; return true; diff --git a/src/main/java/org/wahlzeit/model/Coordinate.java b/src/main/java/org/wahlzeit/model/Coordinate.java index 83a55220b..ae69e6b31 100644 --- a/src/main/java/org/wahlzeit/model/Coordinate.java +++ b/src/main/java/org/wahlzeit/model/Coordinate.java @@ -9,11 +9,11 @@ public interface Coordinate { public CartesianCoordinate asCartesianCoordinate(); - public double getCartesianDistance(Coordinate c); + public double getCartesianDistance(Coordinate c) throws NullPointerException; public SphericCoordinate asSphericCoordinate(); - public double getCentralAngle(Coordinate c); + public double getCentralAngle(Coordinate c) throws NullPointerException; public boolean isEqual(Coordinate c); } diff --git a/src/main/java/org/wahlzeit/model/SphericCoordinate.java b/src/main/java/org/wahlzeit/model/SphericCoordinate.java index 6d7d520f1..c7da1a10b 100644 --- a/src/main/java/org/wahlzeit/model/SphericCoordinate.java +++ b/src/main/java/org/wahlzeit/model/SphericCoordinate.java @@ -5,17 +5,10 @@ package org.wahlzeit.model; -import org.wahlzeit.model.Location; - -public class SphericCoordinate implements Coordinate { +public class SphericCoordinate extends AbstractCoordinate { private double phi, theta, radius; - /** - * The Location object currently associated with this Coordinate. - */ - private Location location; - public SphericCoordinate(double phi, double theta, double radius) { this.phi = phi; this.theta = theta; @@ -27,9 +20,7 @@ public SphericCoordinate(double phi, double theta, double radius, Location l) { this.theta = theta; this.radius = radius; - if (l != null) { - this.setLocation(l); - } + this.setLocation(l); } /** @@ -53,23 +44,6 @@ public double getRadius() { return radius; } - /** - * @methodtype get - */ - public Location getLocation() { - return location; - } - - /** - * @methodtype set (bi-directional with private attribute Location.coordinate) - */ - protected Coordinate setLocation(Location loc) { - this.location = loc; - loc.coordinate = this; - - return this; - } - static SphericCoordinate fromCartesian(CartesianCoordinate c) { double x = c.getX(); double y = c.getY(); @@ -98,44 +72,14 @@ public SphericCoordinate asSphericCoordinate() { return this; } - @Override - public double getCentralAngle(Coordinate c) { - double ro1 = this.phi; - double lam1 = this.theta; - double ro2 = c.asSphericCoordinate().getPhi(); - double lam2 = c.asSphericCoordinate().getTheta(); - - double deltaX = Math.cos(ro2) * Math.cos(lam2) - Math.cos(ro1) * Math.cos(lam1); - double deltaY = Math.cos(ro2) * Math.sin(lam2) - Math.cos(ro1) * Math.sin(lam1); - double deltaZ = Math.sin(ro2) - Math.sin(ro1); - - double C = Math.sqrt(deltaX*deltaX + deltaY*deltaY + deltaZ*deltaZ); - - return 2 * Math.asin(C / 2); - } - - @Override - public boolean isEqual(Coordinate c) { - if (this == c) - return true; - if (c == null) - return false; - - return this.isWithinDistance(c, 0.001); - } - - private boolean isWithinDistance(Coordinate c, double epsilon) { - return (this.getCartesianDistance(c) < epsilon); - } - /** * Custom Java-Object methods for hashCode, equals and toString */ @Override public int hashCode() { int result = 0; - if (location != null) { - result += location.hashCode(); + if (getLocation() != null) { + result += getLocation().hashCode(); } result += 2 * Double.valueOf(radius).hashCode(); result -= 3 * Double.valueOf(theta).hashCode(); @@ -162,8 +106,8 @@ public boolean equals(Object obj) { return false; if (phi != other.phi) return false; - if (location != null && other.location != null && - !location.equals(other.location)) + if (getLocation() != null && other.getLocation() != null && + !getLocation().equals(other.getLocation())) return false; return true; diff --git a/src/test/java/org/wahlzeit/model/CoordinateTest.java b/src/test/java/org/wahlzeit/model/CoordinateTest.java index 60c989ff1..42068d250 100644 --- a/src/test/java/org/wahlzeit/model/CoordinateTest.java +++ b/src/test/java/org/wahlzeit/model/CoordinateTest.java @@ -36,6 +36,7 @@ public void testCartesianCoordinate() { assertTrue(c1.isEqual(c1)); assertFalse(c1.isEqual(c2)); assertTrue(c1.isEqual(new CartesianCoordinate(0, 0, 0))); + assertTrue(c1.isEqual(new CartesianCoordinate(0, 0, 0.001))); // getDistance assertTrue(c1.getCartesianDistance(c1) == 0); @@ -49,7 +50,24 @@ public void testCartesianCoordinate() { assertEquals(0.01, sc1.getCartesianDistance(c2.asSphericCoordinate()), 0.01); // getCentralAngle - assertTrue(sc1.getCentralAngle(c2) >= 0); + assertTrue(c1.getCentralAngle(c2) >= 0); + } + + @Test(expected = NullPointerException.class) + public void testCartesianCoordinateDistanceToNull() { + CartesianCoordinate c1 = new CartesianCoordinate(0, 0, 0); + c1.getCartesianDistance(null); + } + + @Test(expected = NullPointerException.class) + public void testCartesianCoordinateCentralAngleWithNull() { + CartesianCoordinate c1 = new CartesianCoordinate(0, 0, 0); + c1.getCentralAngle(null); + } + + @Test(expected = NullPointerException.class) + public void testCartesianCoordinateConversionFromNull() { + CartesianCoordinate.fromSpheric(null); } @Test @@ -72,21 +90,38 @@ public void testSphericCoordinate() { assertTrue(c1.isEqual(c1)); assertFalse(c1.isEqual(c2)); assertTrue(c1.isEqual(new CartesianCoordinate(0, 0, 0))); + assertTrue(c1.isEqual(new CartesianCoordinate(0, 0, 0.001))); // getDistance assertTrue(c1.getCartesianDistance(c1) == 0); assertEquals(0.01, c1.getCartesianDistance(c2), 0.01); // asCartesianCoordinate - CartesianCoordinate sc1 = c1.asCartesianCoordinate(); - assertTrue(sc1.getX() != Double.NaN); - assertTrue(sc1.getY() != Double.NaN); - assertTrue(sc1.getZ() != Double.NaN); - assertEquals(0.01, sc1.getCartesianDistance(c2.asSphericCoordinate()), 0.01); + CartesianCoordinate cc1 = c1.asCartesianCoordinate(); + assertTrue(cc1.getX() != Double.NaN); + assertTrue(cc1.getY() != Double.NaN); + assertTrue(cc1.getZ() != Double.NaN); + assertEquals(0.01, cc1.getCartesianDistance(c2.asSphericCoordinate()), 0.01); // getCentralAngle assertTrue(c1.getCentralAngle(c2) >= 0); } + @Test(expected = NullPointerException.class) + public void testSphericCoordinateDistanceToNull() { + SphericCoordinate c1 = new SphericCoordinate(0, 0, 0); + c1.getCartesianDistance(null); + } + + @Test(expected = NullPointerException.class) + public void testSphericCoordinateCentralAngleWithNull() { + SphericCoordinate c1 = new SphericCoordinate(0, 0, 0); + c1.getCentralAngle(null); + } + + @Test(expected = NullPointerException.class) + public void testSphericCoordinateConversionFromNull() { + SphericCoordinate.fromCartesian(null); + } }