diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..6c06bcb
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..cc390c0
--- /dev/null
+++ b/.project
@@ -0,0 +1,17 @@
+
+
+ glum
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/buildGlumBin.jardesc b/buildGlumBin.jardesc
new file mode 100644
index 0000000..42edf92
--- /dev/null
+++ b/buildGlumBin.jardesc
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/buildGlumSrc.jardesc b/buildGlumSrc.jardesc
new file mode 100644
index 0000000..5f19168
--- /dev/null
+++ b/buildGlumSrc.jardesc
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/dockingFramesCore-src.jar b/lib/dockingFramesCore-src.jar
new file mode 100644
index 0000000..742b1f9
Binary files /dev/null and b/lib/dockingFramesCore-src.jar differ
diff --git a/lib/dockingFramesCore.jar b/lib/dockingFramesCore.jar
new file mode 100644
index 0000000..0ef9fe9
Binary files /dev/null and b/lib/dockingFramesCore.jar differ
diff --git a/lib/guava-12.0-sources.jar b/lib/guava-12.0-sources.jar
new file mode 100644
index 0000000..f6e0301
Binary files /dev/null and b/lib/guava-12.0-sources.jar differ
diff --git a/lib/guava-12.0.jar b/lib/guava-12.0.jar
new file mode 100644
index 0000000..fefd6b2
Binary files /dev/null and b/lib/guava-12.0.jar differ
diff --git a/lib/miglayout-3.7.2-sources.jar b/lib/miglayout-3.7.2-sources.jar
new file mode 100644
index 0000000..a71e8c8
Binary files /dev/null and b/lib/miglayout-3.7.2-sources.jar differ
diff --git a/lib/miglayout-3.7.2-swing.jar b/lib/miglayout-3.7.2-swing.jar
new file mode 100755
index 0000000..f4b0246
Binary files /dev/null and b/lib/miglayout-3.7.2-swing.jar differ
diff --git a/src/Manifest.txt b/src/Manifest.txt
new file mode 100644
index 0000000..fcb7d37
--- /dev/null
+++ b/src/Manifest.txt
@@ -0,0 +1 @@
+Class-Path: lib/guava-12.0.jar lib/miglayout-3.7.2-sources.jar
diff --git a/src/glum/coord/Convert.java b/src/glum/coord/Convert.java
new file mode 100644
index 0000000..ad5af9b
--- /dev/null
+++ b/src/glum/coord/Convert.java
@@ -0,0 +1,95 @@
+package glum.coord;
+
+/**
+ * Contains conversion multipliers to/from feet, yards, meters, data miles, and nautical miles, as well as angular
+ * values to/from degrees and radians. To convert a value X in units of U to units of
+ * V, use X * Convert.U_TO_V.
+ */
+public class Convert
+{
+ public static final double FEET_TO_METERS = 0.3048;
+ public static final double DM_TO_METERS = 1828.8;
+ public static final double NM_TO_METERS = 1852.0;
+ public static final double MILES_TO_METERS = 1609.344;
+ public static final double YARDS_TO_METERS = 0.9144; // 3 * FEET_TO_METERS
+
+ public static final double METERS_TO_FEET = 1.0 / FEET_TO_METERS;
+ public static final double DM_TO_FEET = 6000.0;
+ public static final double NM_TO_FEET = NM_TO_METERS * METERS_TO_FEET;
+ public static final double MILES_TO_FEET = 5280.0;
+ public static final double YARDS_TO_FEET = 3.0;
+
+ public static final double METERS_TO_DM = 1.0 / DM_TO_METERS;
+ public static final double FEET_TO_DM = FEET_TO_METERS * METERS_TO_DM;
+ public static final double NM_TO_DM = NM_TO_METERS * METERS_TO_DM;
+ public static final double MILES_TO_DM = MILES_TO_METERS * METERS_TO_DM;
+ public static final double YARDS_TO_DM = YARDS_TO_METERS * METERS_TO_DM;
+
+ public static final double METERS_TO_NM = 1.0 / NM_TO_METERS;
+ public static final double FEET_TO_NM = FEET_TO_METERS * METERS_TO_NM;
+ public static final double DM_TO_NM = DM_TO_METERS * METERS_TO_NM;
+ public static final double MILES_TO_NM = MILES_TO_METERS * METERS_TO_NM;
+ public static final double YARDS_TO_NM = YARDS_TO_METERS * NM_TO_METERS;
+
+ public static final double METERS_TO_MILES = 1.0 / MILES_TO_METERS;
+ public static final double FEET_TO_MILES = FEET_TO_METERS * METERS_TO_MILES;
+ public static final double DM_TO_MILES = DM_TO_METERS * METERS_TO_MILES;
+ public static final double NM_TO_MILES = NM_TO_METERS * METERS_TO_MILES;
+ public static final double YARDS_TO_MILES = YARDS_TO_METERS * METERS_TO_MILES;
+
+ public static final double METERS_TO_YARDS = 1.0 / YARDS_TO_METERS;
+ public static final double FEET_TO_YARDS = 1.0 / 3.0;
+ public static final double DM_TO_YARDS = 2000.0;
+ public static final double NM_TO_YARDS = NM_TO_METERS * METERS_TO_YARDS;
+ public static final double MILES_TO_YARDS = 1760.0;
+
+ public static final double RAD_TO_DEG = 180.0 / Math.PI;
+ public static final double DEG_TO_RAD = Math.PI / 180.0;
+
+ public static final double SECS_TO_MSECS = 1000.0;
+ public static final double MSECS_TO_SECS = 1.0 / SECS_TO_MSECS;
+
+ public static final int MINS_TO_SECS = 60;
+ public static final int HOURS_TO_MINS = 60;
+ public static final int HOURS_TO_SECS = HOURS_TO_MINS * MINS_TO_SECS;
+
+ public static final double SECS_TO_MINS = 1 / MINS_TO_SECS;
+ public static final double MINS_TO_HOURS = 1 / HOURS_TO_MINS;
+ public static final double SECS_TO_HOURS = 1 / HOURS_TO_SECS;
+
+ /**
+ * Constructor
+ */
+ private Convert()
+ {
+ }
+
+ /**
+ * Converts an angle to a bearing
+ */
+ public static double angleToBearing(double aAngle)
+ {
+ double bearing;
+
+ bearing = 180 - (aAngle + 90);
+ if (bearing < 0)
+ bearing += 360;
+
+ return bearing;
+ }
+
+ /**
+ * Converts a bearing to an angle
+ */
+ public static double bearingToAngle(double aBearing)
+ {
+ double angle;
+
+ angle = 180 - (aBearing + 90);
+ if (angle < 0)
+ angle += 360;
+
+ return angle;
+ }
+
+}
diff --git a/src/glum/coord/CoordUtil.java b/src/glum/coord/CoordUtil.java
new file mode 100644
index 0000000..c0fa1a6
--- /dev/null
+++ b/src/glum/coord/CoordUtil.java
@@ -0,0 +1,197 @@
+package glum.coord;
+
+
+/** Provides a few useful functions on coordinates, such as converting
+* to a user-presentable string.
+*/
+public class CoordUtil
+{
+ /** Convert a Lat/Lon to a pair of DEG:MM:SS H strings. H is the
+ * hemisphere, N or S for lat, E or W for lon. The default separator
+ * string LL_SEP is used.
+ */
+ public static String LatLonToString (LatLon ll)
+ {
+ return ll == null ? "" : LatLonToString (ll, LL_SEP);
+ }
+
+ /** Same as the other LatLonToString, excepts this one uses the
+ * given sep string to separate the Lat and Lon.
+ */
+ public static String LatLonToString (LatLon ll, String sep)
+ {
+ return ll == null ? "" :
+ LatToString (ll.lat) + LL_SEP + LonToString (ll.lon);
+ }
+
+ /** Converts the given lat to DD:MM:SS H. */
+
+ public static String LatToString (double lat)
+ {
+ return LatToString (lat, true);
+ }
+
+ /** Converts the given lat to DD:MM:SS H if
+ * include_seconds is true. If it's false, then the
+ * :SS part is left off.
+ */
+
+ public static String LatToString (double lat, boolean include_seconds)
+ {
+ DMS dms = new DMS (lat);
+ StringBuffer s = new StringBuffer();
+
+ if ( dms.degrees < 10 )
+ s.append ("0");
+ s.append (dms.degrees);
+ s.append (":");
+ if ( dms.minutes < 10 )
+ s.append ("0");
+ s.append (dms.minutes);
+ if ( include_seconds )
+ {
+ s.append (":");
+ if ( dms.seconds < 10 )
+ s.append ("0");
+ s.append (dms.seconds);
+ }
+ s.append (lat >= 0 ? " N" : " S");
+ return s.toString();
+ }
+
+ /** Similar to LatToString except that the degrees
+ * part is DDD instead of DD. */
+
+ public static String LonToString (double lon)
+ {
+ return LonToString (lon, true);
+ }
+
+ /** Similar to LatToString except that the degrees
+ * part is DDD instead of DD. */
+
+ public static String LonToString (double lon, boolean include_seconds)
+ {
+ DMS dms = new DMS (lon);
+ StringBuffer s = new StringBuffer();
+
+ if ( dms.degrees < 100 )
+ s.append ("0");
+ if ( dms.degrees < 10 )
+ s.append ("0");
+ s.append (dms.degrees);
+ s.append (":");
+ if ( dms.minutes < 10 )
+ s.append ("0");
+ s.append (dms.minutes);
+ if ( include_seconds )
+ {
+ s.append (":");
+ if ( dms.seconds < 10 )
+ s.append ("0");
+ s.append (dms.seconds);
+ }
+ s.append (lon >= 0 ? " E" : " W");
+ return s.toString();
+ }
+
+ /** Converts dmsh_string to a double value.
+ * The string format should match the output of the
+ * LatToString formats, including hemisphere.
+ * If a hemisphere character is not part of the string, the
+ * returned value will be non-negative.
+ */
+ public static double StringToLat (String dmsh_string)
+ {
+ if ( dmsh_string == null || dmsh_string.length() == 0 )
+ return 0.0;
+
+ int dms [] = StringToDMS (dmsh_string);
+
+ if ( dms.length == 3 )
+ return new Degrees (dms[0], dms[1], dms[2]).degrees;
+ else return 0.0;
+ }
+
+ /** {@see StringToLat} */
+
+ public static double StringToLon (String dmsh_string)
+ {
+ // Because we aren't doing any range or hemisphere error
+ // checking, a lon value is identical to a lat value.
+ return StringToLat (dmsh_string);
+ }
+
+ /** Converts dmsh_string to a an array of
+ * 3 ints representing degrees, minutes, and seconds.
+ * if a hemisphere character is present (one of NSEW or
+ * nsew), and it represents a souther or western hemisphere,
+ * then the degrees value, in index 0 of the returned array,
+ * will be a non-positive number.
+ */
+ public static int [] StringToDMS (String dmsh_string)
+ {
+ if ( dmsh_string == null || dmsh_string.length() == 0 )
+ return null;
+
+ char chars [] = dmsh_string.toCharArray();
+ int dms [] = new int [ 3 ];
+
+ dms[0] = 0;
+ for ( int i = 0, j = 0; i < chars.length; i++ )
+ {
+ char c = chars[i];
+
+ if ( c == ' ' || c == ' ' ) // Space or tab.
+ continue;
+ else if ( c >= '0' && c <= '9' && j < 3 )
+ dms[j] = dms[j] * 10 + c - '0';
+ else if ( c == ':' )
+ {
+ j++;
+ dms[j] = 0;
+ }
+ else if ( c == 'S' || c == 's' || c == 'W' || c == 'w' )
+ dms[0] = -dms[0];
+ }
+
+ return dms;
+ }
+
+ public static class DMS
+ {
+ public DMS (double deg)
+ {
+ if ( deg < 0 ) deg = -deg;
+ degrees = (int) deg;
+ minutes = (int) (deg * 60) % 60;
+ seconds = (int) (deg * 3600) % 60;
+ }
+ public int degrees, minutes, seconds;
+ }
+
+ public static class Degrees
+ {
+ public Degrees (int deg, int min, int sec)
+ {
+ degrees = Math.abs (deg) +
+ Math.abs(min) / 60.0 +
+ Math.abs(sec) / 3600.0;
+ if ( deg < 0 || min < 0 || sec < 0 )
+ degrees = -degrees;
+ }
+ public Degrees (int deg, int min, int sec, char hemisphere)
+ {
+ this (deg, min, sec);
+ if ( hemisphere == 'N' || hemisphere == 'n' ||
+ hemisphere == 'E' || hemisphere == 'e' )
+ degrees = Math.abs (degrees);
+ else if ( hemisphere == 'S' || hemisphere == 's' ||
+ hemisphere == 'W' || hemisphere == 'w' )
+ degrees = -Math.abs (degrees);
+ }
+ public double degrees;
+ }
+
+ public static String LL_SEP = " / ";
+}
diff --git a/src/glum/coord/Epsilon.java b/src/glum/coord/Epsilon.java
new file mode 100644
index 0000000..3c4012a
--- /dev/null
+++ b/src/glum/coord/Epsilon.java
@@ -0,0 +1,43 @@
+package glum.coord;
+
+/** Determines if two numbers are close, usually as a way to say
+* that they are equal. Close is defined to mean that their difference
+* is less than some small number, which is either supplied by the caller
+* or is EPSILON.
+*
For longitude near the equator, a difference of EPSILON is about
+* 3.65 feet (where the earth's circumference is about 21913.3 DM, or
+* about 60.87 DM per degree longitude). For DataMile measurements, it's
+* about 0.72 inches.
+*/
+
+public class Epsilon
+{
+ /** The measure of closeness; set to 0.00001. */
+ public static final double EPSILON = 0.00001;
+
+ public static boolean close (float a, float b)
+ {
+ float diff = a - b;
+ return diff < EPSILON && diff > -EPSILON;
+ }
+
+ public static boolean close (float a, float b, float epsilon)
+ {
+ float diff = a - b;
+ return diff < epsilon && diff > -epsilon;
+ }
+
+ public static boolean close (double a, double b)
+ {
+ double diff = a - b;
+ return diff < EPSILON && diff > -EPSILON;
+ }
+
+ public static boolean close (double a, double b, float epsilon)
+ {
+ double diff = a - b;
+ return diff < EPSILON && diff > -EPSILON;
+ }
+
+ private Epsilon () { }
+}
diff --git a/src/glum/coord/GeoUtil.java b/src/glum/coord/GeoUtil.java
new file mode 100644
index 0000000..4f76522
--- /dev/null
+++ b/src/glum/coord/GeoUtil.java
@@ -0,0 +1,97 @@
+package glum.coord;
+
+/**
+ * Contains a collection of utility methods to perform linear algebra using the objects from this package.
+ */
+public class GeoUtil
+{
+ /**
+ * realSqr returns aNum*aNum
+ */
+ public static double realSqr(double aNum)
+ {
+ return aNum * aNum;
+ }
+
+ /**
+ * computeDotProduct - Returns the dot product of vector1 and vector2
+ */
+ public static double computeDotProduct(Point3D vector1, Point3D vector2)
+ {
+ return vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z;
+ }
+
+ /**
+ * computeDistance - Returns the distance between pt1 and pt2
+ */
+ public static double computeDistance(Point3D pt1, Point3D pt2)
+ {
+ return Math.sqrt(realSqr(pt1.x - pt2.x) + realSqr(pt1.y - pt2.y) + realSqr(pt1.z - pt2.z));
+ }
+
+ /**
+ * computeDistanceSquare - Returns the squared distance between pt1 and pt2
+ */
+ public static double computeDistanceSquare(Point3D pt1, Point3D pt2)
+ {
+ return realSqr(pt1.x - pt2.x) + realSqr(pt1.y - pt2.y) + realSqr(pt1.z - pt2.z);
+ }
+
+ /**
+ * computeLength - Returns the magnitude of aVector
+ */
+ public static double computeLength(Point3D aVector)
+ {
+ return Math.sqrt(realSqr(aVector.x) + realSqr(aVector.y) + realSqr(aVector.z));
+ }
+
+ /**
+ * computeNormal - Returns the R.H.R normal defined by the 3 points
+ */
+ public static void computeNormal(Point3D pt1, Point3D pt2, Point3D pt3, Point3D aNormal)
+ {
+ Point3D vector1, vector2;
+
+ vector1 = new Point3D();
+ vector2 = new Point3D();
+ computeVector(pt1, pt3, vector1);
+ computeVector(pt3, pt2, vector2);
+
+ // ! Not sure why I have to negate all the values; Need to refer to linear alg.
+//! aNormal.x = vector1.y*vector2.z - vector1.z*vector2.y;
+//! aNormal.y = vector1.z*vector2.x - vector1.x*vector2.z;
+//! aNormal.z = vector1.x*vector2.y - vector1.y*vector2.x;
+ aNormal.x = -(vector1.y * vector2.z - vector1.z * vector2.y);
+ aNormal.y = -(vector1.z * vector2.x - vector1.x * vector2.z);
+ aNormal.z = -(vector1.x * vector2.y - vector1.y * vector2.x);
+
+ // Normalize the vector
+ normalizeVector(aNormal);
+ }
+
+ /**
+ * computeVector - Returns the vector defined by the 2 points
+ */
+ public static void computeVector(Point3D pt1, Point3D pt2, Point3D aVector)
+ {
+ aVector.x = pt2.x - pt1.x;
+ aVector.y = pt2.y - pt1.y;
+ aVector.z = pt2.z - pt1.z;
+ }
+
+ /**
+ * normalizeVector - Normalizes aVector so that its length is 1
+ */
+ public static void normalizeVector(Point3D aVector)
+ {
+ double length;
+
+ length = computeLength(aVector);
+
+ // Normalize the vector
+ aVector.x = aVector.x / length;
+ aVector.y = aVector.y / length;
+ aVector.z = aVector.z / length;
+ }
+
+}
diff --git a/src/glum/coord/LatLon.java b/src/glum/coord/LatLon.java
new file mode 100644
index 0000000..c9a954c
--- /dev/null
+++ b/src/glum/coord/LatLon.java
@@ -0,0 +1,111 @@
+package glum.coord;
+
+/** Simple class for Lat/Lon values. */
+public class LatLon
+{
+ public double lat;
+ public double lon;
+
+ public LatLon()
+ {
+ }
+
+ public LatLon(LatLon latlon)
+ {
+ if (latlon != null)
+ {
+ lat = latlon.lat;
+ lon = latlon.lon;
+ }
+ }
+
+ public LatLon(double lat, double lon)
+ {
+ this.lat = lat;
+ this.lon = lon;
+ }
+
+ public LatLon(String lat_string, String lon_string)
+ {
+ set(lat_string, lon_string);
+ }
+
+ public void set(double lat, double lon)
+ {
+ this.lat = lat;
+ this.lon = lon;
+ }
+
+ public void set(LatLon latlon)
+ {
+ if (latlon != null)
+ {
+ lat = latlon.lat;
+ lon = latlon.lon;
+ }
+ }
+
+ public void set(String lat_string, String lon_string)
+ {
+ lat = CoordUtil.StringToLat(lat_string);
+ lon = CoordUtil.StringToLon(lon_string);
+ }
+
+ public void normalize()
+ {
+ if (lat > 90)
+ lat = 90;
+ else if (lat < -90)
+ lat = -90;
+
+ if (lon > 180)
+ lon -= 360;
+ else if (lon < -180)
+ lon += 360;
+ }
+
+ /**
+ * Tests to see if the given object is the same lat/lon as this position.
+ * "Same" really means "very, very close," as defined by {@link Epsilon}.
+ *
+ * @return True if obj is a LatLon and is very close to our lat/lon position.
+ * False otherwise.
+ */
+ @Override
+ public boolean equals(Object obj)
+ {
+ return (obj instanceof LatLon) && Epsilon.close(lat, ((LatLon)obj).lat) && Epsilon.close(lon, ((LatLon)obj).lon);
+ }
+
+ @Override
+ public String toString()
+ {
+ return CoordUtil.LatLonToString(this);
+ }
+
+ /**
+ * Returns the change in latitude
+ */
+ static public double computeDeltaLat(double lat1, double lat2)
+ {
+ return lat2 - lat1;
+ }
+
+ /**
+ * Returns the change in longitude
+ */
+ static public double computeDeltaLon(double lon1, double lon2)
+ {
+ double dLon;
+
+ dLon = lon2 - lon1;
+ if (Math.abs(dLon) < 180)
+ return dLon;
+
+ if (dLon > 180)
+ return dLon - 360;
+ else
+ return dLon + 360;
+ }
+
+}
diff --git a/src/glum/coord/Point2D.java b/src/glum/coord/Point2D.java
new file mode 100644
index 0000000..7bff1fe
--- /dev/null
+++ b/src/glum/coord/Point2D.java
@@ -0,0 +1,37 @@
+package glum.coord;
+
+public class Point2D
+{
+ public double x;
+ public double y;
+
+ public Point2D () { }
+
+ public Point2D (Point2D pt)
+ { if ( pt != null ) { x = pt.x; y = pt.y; } }
+
+ public Point2D (double x, double y)
+ { this.x = x; this.y = y; }
+
+ public void set (double x, double y)
+ { this.x = x; this.y = y; }
+
+ public void set (Point2D pt)
+ { if ( pt != null ) { x = pt.x; y = pt.y; } }
+
+ public double distance (Point2D aPt)
+ {
+ if (aPt == null)
+ return 0;
+
+ return Math.sqrt((aPt.x - x)*(aPt.x - x) + (aPt.y - y)*(aPt.y - y));
+ }
+
+ @Override
+ public boolean equals (Object obj)
+ {
+ return (obj instanceof Point2D) &&
+ Epsilon.close (x, ((Point2D) obj).x) &&
+ Epsilon.close (y, ((Point2D) obj).y);
+ }
+}
diff --git a/src/glum/coord/Point2Di.java b/src/glum/coord/Point2Di.java
new file mode 100644
index 0000000..f7f09d5
--- /dev/null
+++ b/src/glum/coord/Point2Di.java
@@ -0,0 +1,27 @@
+package glum.coord;
+
+public class Point2Di
+{
+ public int x;
+ public int y;
+
+ public Point2Di () { }
+
+ public Point2Di (Point2Di pt)
+ { if ( pt != null ) { x = pt.x; y = pt.y; } }
+
+ public Point2Di (int x, int y) { this.x = x; this.y = y; }
+
+ public void set (int x, int y) { this.x = x; this.y = y; }
+
+ public void set (Point2Di pt)
+ { if ( pt != null ) { x = pt.x; y = pt.y; } }
+
+ @Override
+ public boolean equals (Object obj)
+ {
+ return (obj instanceof Point2Di) &&
+ x == ((Point2Di) obj).x &&
+ y == ((Point2Di) obj).y;
+ }
+}
diff --git a/src/glum/coord/Point3D.java b/src/glum/coord/Point3D.java
new file mode 100644
index 0000000..7fabc60
--- /dev/null
+++ b/src/glum/coord/Point3D.java
@@ -0,0 +1,42 @@
+package glum.coord;
+
+/** A class for representing any 3-Dimensional vector, which could be
+* a position, a velocity, or a rotation. No information about units
+* is assumed or implied.
+*/
+
+public class Point3D
+{
+ public double x;
+ public double y;
+ public double z;
+
+ public Point3D () { }
+
+ public Point3D (Point3D pt)
+ { if ( pt != null ) { x = pt.x; y = pt.y; z = pt.z; } }
+
+ public Point3D (double x, double y, double z)
+ { this.x = x; this.y = y; this.z = z; }
+
+ public void set (double x, double y, double z)
+ { this.x = x; this.y = y; this.z = z; }
+
+ public void set (Point3D pt)
+ { if ( pt != null ) { x = pt.x; y = pt.y; z = pt.z; } }
+
+ @Override
+ public boolean equals (Object obj)
+ {
+ return (obj instanceof Point3D) &&
+ Epsilon.close (x, ((Point3D) obj).x) &&
+ Epsilon.close (y, ((Point3D) obj).y) &&
+ Epsilon.close (z, ((Point3D) obj).z);
+ }
+
+ @Override
+ public String toString()
+ {
+ return new String("(" + x + ", " + y + ", " + z + ")");
+ }
+}
diff --git a/src/glum/coord/RngBrg.java b/src/glum/coord/RngBrg.java
new file mode 100644
index 0000000..cc79fe2
--- /dev/null
+++ b/src/glum/coord/RngBrg.java
@@ -0,0 +1,47 @@
+package glum.coord;
+
+public class RngBrg
+{
+ public double rng;
+ public double brg;
+
+ public RngBrg() { }
+
+ public RngBrg(RngBrg pt)
+ {
+ if ( pt != null )
+ {
+ rng = pt.rng;
+ brg = pt.brg;
+ }
+ }
+
+ public RngBrg (double rng, double brg)
+ {
+ this.rng = rng;
+ this.brg = brg;
+ }
+
+ public void set (double rng, double brg)
+ {
+ this.rng = rng;
+ this.brg = brg;
+ }
+
+ public void set (RngBrg pt)
+ {
+ if ( pt != null )
+ {
+ rng = pt.rng;
+ brg = pt.brg;
+ }
+ }
+
+ @Override
+ public boolean equals (Object obj)
+ {
+ return (obj instanceof RngBrg) &&
+ Epsilon.close (rng, ((RngBrg) obj).rng) &&
+ Epsilon.close (brg, ((RngBrg) obj).brg);
+ }
+}
diff --git a/src/glum/coord/UV.java b/src/glum/coord/UV.java
new file mode 100644
index 0000000..8c7150d
--- /dev/null
+++ b/src/glum/coord/UV.java
@@ -0,0 +1,26 @@
+package glum.coord;
+
+public class UV extends Point2D
+{
+ public UV ()
+ {
+ x = 0;
+ y = 0;
+ }
+
+ public UV (Point2D pt)
+ {
+ if (pt != null)
+ {
+ x = pt.x;
+ y = pt.y;
+ }
+ }
+
+ public UV (double x, double y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+}
diff --git a/src/glum/database/QueryItem.java b/src/glum/database/QueryItem.java
new file mode 100644
index 0000000..6a8aa95
--- /dev/null
+++ b/src/glum/database/QueryItem.java
@@ -0,0 +1,15 @@
+package glum.database;
+
+public abstract interface QueryItem>
+{
+ /**
+ * Returns the corresponding value associated with aEnum
+ */
+ public Object getValue(G1 aEnum);
+
+ /**
+ * Sets in the aObj as the corresponding value to aEnum
+ */
+ public void setValue(G1 aEnum, Object aObj);
+
+}
diff --git a/src/glum/database/QueryItemComparator.java b/src/glum/database/QueryItemComparator.java
new file mode 100644
index 0000000..3365316
--- /dev/null
+++ b/src/glum/database/QueryItemComparator.java
@@ -0,0 +1,62 @@
+package glum.database;
+
+import java.util.Comparator;
+
+public class QueryItemComparator, G2 extends Enum>> implements Comparator
+{
+ private G2 sortKey;
+
+ public QueryItemComparator(G2 aSortKey)
+ {
+ sortKey = aSortKey;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public int compare(G1 item1, G1 item2)
+ {
+ Comparable