/** Construct a sided plane from two points and a third normal vector. */ public static SidedPlane constructNormalizedPerpendicularSidedPlane(final Vector insidePoint, final Vector normalVector, final Vector point1, final Vector point2) { final Vector pointsVector = new Vector(point1.x - point2.x, point1.y - point2.y, point1.z - point2.z); final Vector newNormalVector = new Vector(normalVector, pointsVector); try { // To construct the plane, we now just need D, which is simply the negative of the evaluation of the circle normal vector at one of the points. return new SidedPlane(insidePoint, newNormalVector, -newNormalVector.dotProduct(point1)); } catch (IllegalArgumentException e) { return null; } }
/** * Checks if three points are coplanar in any of the three planes they can describe. * The planes are all assumed to go through the origin. * * @param A The first point. * @param B The second point. * @param C The third point * @return true if provided points are coplanar in any of the three planes they can describe. */ public static boolean arePointsCoplanar(final GeoPoint A, final GeoPoint B, final GeoPoint C) { return Vector.crossProductEvaluateIsZero(A, B, C) || Vector.crossProductEvaluateIsZero(A, C, B) || Vector.crossProductEvaluateIsZero(B, C, A); }
@Override public boolean equals(Object o) { if (!super.equals(o)) return false; if (!(o instanceof Plane)) return false; Plane other = (Plane) o; return other.D == D; }
/** * Compute a normalized unit vector based on the current vector. * * @return the normalized vector, or null if the current vector has * a magnitude of zero. */ public Vector normalize() { double denom = magnitude(); if (denom < MINIMUM_RESOLUTION) // Degenerate, can't normalize return null; double normFactor = 1.0 / denom; return new Vector(x * normFactor, y * normFactor, z * normFactor); }
/** * Reverse modify a point to produce a GeoPoint in normal space. * @param planetModel is the planet model. * @param point is the translated point. * @param transX is the translation x value. * @param transY is the translation y value. * @param transZ is the translation z value. * @param sinRA is the sine of the ascension angle. * @param cosRA is the cosine of the ascension angle. * @param sinHA is the sine of the height angle. * @param cosHA is the cosine of the height angle. * @return the original point. */ protected static GeoPoint reverseModify(final PlanetModel planetModel, final Vector point, final double transX, final double transY, final double transZ, final double sinRA, final double cosRA, final double sinHA, final double cosHA) { final Vector result = point.rotateXZ(-sinHA, cosHA).rotateXY(-sinRA, cosRA).translate(-transX, -transY, -transZ); return planetModel.createSurfacePoint(result.x, result.y, result.z); }
/** * Modify a point to produce a vector in translated/rotated space. * @param start is the start point. * @param transX is the translation x value. * @param transY is the translation y value. * @param transZ is the translation z value. * @param sinRA is the sine of the ascension angle. * @param cosRA is the cosine of the ascension angle. * @param sinHA is the sine of the height angle. * @param cosHA is the cosine of the height angle. * @return the modified point. */ protected static Vector modify(final GeoPoint start, final double transX, final double transY, final double transZ, final double sinRA, final double cosRA, final double sinHA, final double cosHA) { return start.translate(transX, transY, transZ).rotateXY(sinRA, cosRA).rotateXZ(sinHA, cosHA); }
/** Compute the linear magnitude of the point. * @return the magnitude. */ @Override public double magnitude() { double mag = this.magnitude;//volatile-read once if (mag == Double.NEGATIVE_INFINITY) { this.magnitude = mag = super.magnitude(); } return mag; }
/** * Translate vector. */ public Vector translate(final double xOffset, final double yOffset, final double zOffset) { return new Vector(x - xOffset, y - yOffset, z - zOffset); }
/** * Compute the straight-line distance to a point described by the * vector taken from the origin. * Monotonically increasing for arc distances up to PI. * * @param v is the vector to compute a distance to. * @return the linear distance. */ public double linearDistance(final Vector v) { return Math.sqrt(linearDistanceSquared(v)); }
/** * Compute the normal (perpendicular) distance to a vector described by a * vector taken from the origin. * Monotonically increasing for arc distances up to PI/2. * * @param v is the vector to compute a distance to. * @return the normal distance. */ public double normalDistance(final Vector v) { return Math.sqrt(normalDistanceSquared(v)); }
/** * Compute the square of the normal distance to a vector described by a * vector taken from the origin. * Monotonically increasing for arc distances up to PI/2. * * @param v is the vector to compute a distance to. * @return the square of the normal distance. */ public double normalDistanceSquared(final Vector v) { double t = dotProduct(v); double deltaX = this.x * t - v.x; double deltaY = this.y * t - v.y; double deltaZ = this.z * t - v.z; return deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ; }
@Override public int hashCode() { int result = super.hashCode(); long temp; temp = Double.doubleToLongBits(D); result = 31 * result + (int) (temp ^ (temp >>> 32)); return result; } }
/** * Rotate vector counter-clockwise in x-y by an angle. */ public Vector rotateXY(final double angle) { return rotateXY(Math.sin(angle), Math.cos(angle)); }
/** * Build a normalized plane, so that the vector is normalized. * * @return the normalized plane object, or null if the plane is indeterminate. */ public Plane normalize() { Vector normVect = super.normalize(); if (normVect == null) return null; return new Plane(normVect, this.D); }
/** * Compute the magnitude of this vector. * * @return the magnitude. */ public double magnitude() { return magnitude(x,y,z); }
/** * Rotate vector counter-clockwise in x-y by an angle, expressed as sin and cos. */ public Vector rotateXY(final double sinAngle, final double cosAngle) { return new Vector(x * cosAngle - y * sinAngle, x * sinAngle + y * cosAngle, z); }
/** * Compute the straight-line distance to a point described by the * vector taken from the origin. * Monotonically increasing for arc distances up to PI. * * @param x is the x part of the vector to compute a distance to. * @param y is the y part of the vector to compute a distance to. * @param z is the z part of the vector to compute a distance to. * @return the linear distance. */ public double linearDistance(final double x, final double y, final double z) { return Math.sqrt(linearDistanceSquared(x, y, z)); }
/** * Compute the normal (perpendicular) distance to a vector described by a * vector taken from the origin. * Monotonically increasing for arc distances up to PI/2. * * @param x is the x part of the vector to compute a distance to. * @param y is the y part of the vector to compute a distance to. * @param z is the z part of the vector to compute a distance to. * @return the normal distance. */ public double normalDistance(final double x, final double y, final double z) { return Math.sqrt(normalDistanceSquared(x, y, z)); }
/** * Compute the square of the normal distance to a vector described by a * vector taken from the origin. * Monotonically increasing for arc distances up to PI/2. * * @param x is the x part of the vector to compute a distance to. * @param y is the y part of the vector to compute a distance to. * @param z is the z part of the vector to compute a distance to. * @return the square of the normal distance. */ public double normalDistanceSquared(final double x, final double y, final double z) { double t = dotProduct(x, y, z); double deltaX = this.x * t - x; double deltaY = this.y * t - y; double deltaZ = this.z * t - z; return deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ; }
final Vector planeNormal = new Vector( point1.x - point2.x, point1.y - point2.y, point1.z - point2.z, point2.x - point3.x, point2.y - point3.y, point2.z - point3.z); rval = new SidedPlane(insidePoint, planeNormal, -planeNormal.dotProduct(point2)); } catch (IllegalArgumentException e) { final Vector planeNormal = new Vector( point1.x - point3.x, point1.y - point3.y, point1.z - point3.z, point3.x - point2.x, point3.y - point2.y, point3.z - point2.z); rval = new SidedPlane(insidePoint, planeNormal, -planeNormal.dotProduct(point3)); } catch (IllegalArgumentException e) { final Vector planeNormal = new Vector( point3.x - point1.x, point3.y - point1.y, point3.z - point1.z, point1.x - point2.x, point1.y - point2.y, point1.z - point2.z); rval = new SidedPlane(insidePoint, planeNormal, -planeNormal.dotProduct(point1)); } catch (IllegalArgumentException e) {