/** * Computes the axis plane that this plane lies closest to. * <p> * Geometries lying in this plane undergo least distortion * (and have maximum area) * when projected to the closest axis plane. * This provides optimal conditioning for * computing a Point-in-Polygon test. * * @return the index of the closest axis plane. */ public int closestAxisPlane() { double xmag = Math.abs(normal.getX()); double ymag = Math.abs(normal.getY()); double zmag = Math.abs(normal.getZ()); if (xmag > ymag) { if (xmag > zmag) return YZ_PLANE; else return XY_PLANE; } // y >= x else if (zmag > ymag) { return XY_PLANE; } // y >= z return XZ_PLANE; }
/** * Computes the axis plane that this plane lies closest to. * <p> * Geometries lying in this plane undergo least distortion * (and have maximum area) * when projected to the closest axis plane. * This provides optimal conditioning for * computing a Point-in-Polygon test. * * @return the index of the closest axis plane. */ public int closestAxisPlane() { double xmag = Math.abs(normal.getX()); double ymag = Math.abs(normal.getY()); double zmag = Math.abs(normal.getZ()); if (xmag > ymag) { if (xmag > zmag) return YZ_PLANE; else return XY_PLANE; } // y >= x else if (zmag > ymag) { return XY_PLANE; } // y >= z return XZ_PLANE; }
/** * Compute intersection point of two vectors * @param p1 Origin point * @param v1 Direction from p1 * @param p2 Origin point 2 * @param v2 Direction of p2 * @return Null if vectors are collinear or if intersection is done behind one of origin point */ public static Coordinate vectorIntersection(Coordinate p1, Vector3D v1, Coordinate p2, Vector3D v2) { double delta; Coordinate i = null; // Cramer's rule for compute intersection of two planes delta = v1.getX() * (-v2.getY()) - (-v1.getY()) * v2.getX(); if (delta != 0) { double k = ((p2.x - p1.x) * (-v2.getY()) - (p2.y - p1.y) * (-v2.getX())) / delta; // Fix precision problem with big decimal i = new Coordinate(p1.x + k * v1.getX(), p1.y + k * v1.getY(), p1.z + k * v1.getZ()); if(new LineSegment(p1, new Coordinate(p1.x + v1.getX(), p1.y + v1.getY())).projectionFactor(i) < 0 || new LineSegment(p2, new Coordinate(p2.x + v2.getX(), p2.y + v2.getY())).projectionFactor(i) < 0) { return null; } } return i; }
/** * Compute intersection point of two vectors * @param p1 Origin point * @param v1 Direction from p1 * @param p2 Origin point 2 * @param v2 Direction of p2 * @return Null if vectors are collinear or if intersection is done behind one of origin point */ public static Coordinate vectorIntersection(Coordinate p1, Vector3D v1, Coordinate p2, Vector3D v2) { double delta; Coordinate i = null; // Cramer's rule for compute intersection of two planes delta = v1.getX() * (-v2.getY()) - (-v1.getY()) * v2.getX(); if (delta != 0) { double k = ((p2.x - p1.x) * (-v2.getY()) - (p2.y - p1.y) * (-v2.getX())) / delta; // Fix precision problem with big decimal i = new Coordinate(p1.x + k * v1.getX(), p1.y + k * v1.getY(), p1.z + k * v1.getZ()); if(new LineSegment(p1, new Coordinate(p1.x + v1.getX(), p1.y + v1.getY())).projectionFactor(i) < 0 || new LineSegment(p2, new Coordinate(p2.x + v2.getX(), p2.y + v2.getY())).projectionFactor(i) < 0) { return null; } } return i; }
/** * Get the vector with the highest down slope in the plan. * @param normal * @param epsilon * @return the steepest vector. */ public static Vector3D getSteepestVector(final Vector3D normal, final double epsilon) { if (Math.abs(normal.getX()) < epsilon && Math.abs(normal.getY()) < epsilon) { return new Vector3D(0, 0, 0); } Vector3D slope; if (Math.abs(normal.getX()) < epsilon) { slope = new Vector3D(0, 1, -normal.getY() / normal.getZ()); } else if (Math.abs(normal.getY()) < epsilon) { slope = new Vector3D(1, 0, -normal.getX() / normal.getZ()); } else { slope = new Vector3D(normal.getX() / normal.getY(), 1, -1 / normal.getZ() * (normal.getX() * normal.getX() / normal.getY() + normal.getY())); } //We want the vector to be low-oriented. if (slope.getZ() > epsilon) { slope = new Vector3D(-slope.getX(), -slope.getY(), -slope.getZ()); } //We normalize it return slope.normalize(); }
/** * * @param normal Plane normal * @param epsilon Epsilon value ex:1e-12 * @return The steepest slope of this plane in degree. */ public static double getSlopeInPercent(final Vector3D normal, final double epsilon) { Vector3D vector = getSteepestVector(normal, epsilon); if(Math.abs(vector.getZ()) < epsilon) { return 0; } else { return (Math.abs(vector.getZ()) / new Vector2D(vector.getX(), vector.getY()).length()) * 100; } }
/** * Get the vector with the highest down slope in the plan. * @param normal * @param epsilon * @return the steepest vector. */ public static Vector3D getSteepestVector(final Vector3D normal, final double epsilon) { if (Math.abs(normal.getX()) < epsilon && Math.abs(normal.getY()) < epsilon) { return new Vector3D(0, 0, 0); } Vector3D slope; if (Math.abs(normal.getX()) < epsilon) { slope = new Vector3D(0, 1, -normal.getY() / normal.getZ()); } else if (Math.abs(normal.getY()) < epsilon) { slope = new Vector3D(1, 0, -normal.getX() / normal.getZ()); } else { slope = new Vector3D(normal.getX() / normal.getY(), 1, -1 / normal.getZ() * (normal.getX() * normal.getX() / normal.getY() + normal.getY())); } //We want the vector to be low-oriented. if (slope.getZ() > epsilon) { slope = new Vector3D(-slope.getX(), -slope.getY(), -slope.getZ()); } //We normalize it return slope.normalize(); }
/** * * @param normal Plane normal * @param epsilon Epsilon value ex:1e-12 * @return The steepest slope of this plane in degree. */ public static double getSlopeInPercent(final Vector3D normal, final double epsilon) { Vector3D vector = getSteepestVector(normal, epsilon); if(Math.abs(vector.getZ()) < epsilon) { return 0; } else { return (Math.abs(vector.getZ()) / new Vector2D(vector.getX(), vector.getY()).length()) * 100; } } }
/** * Compute the aspect in degree. The geometry must be a triangle. * @param geometry Polygon triangle * @return aspect in degree * @throws IllegalArgumentException ST_TriangleAspect accept only triangles */ public static Double computeAspect(Geometry geometry) throws IllegalArgumentException { if (geometry == null) { return null; } Vector3D vector = TriMarkers.getSteepestVector(TriMarkers.getNormalVector(TINFeatureFactory.createTriangle(geometry)), TINFeatureFactory.EPSILON); if (vector.length() < TINFeatureFactory.EPSILON) { return 0d; } else { Vector2D v = new Vector2D(vector.getX(), vector.getY()); return measureFromNorth(Math.toDegrees(v.angle())); } }
/** * Compute the aspect in degree. The geometry must be a triangle. * @param geometry Polygon triangle * @return aspect in degree * @throws IllegalArgumentException ST_TriangleAspect accept only triangles */ public static Double computeAspect(Geometry geometry) throws IllegalArgumentException { if (geometry == null) { return null; } Vector3D vector = TriMarkers.getSteepestVector(TriMarkers.getNormalVector(TINFeatureFactory.createTriangle(geometry)), TINFeatureFactory.EPSILON); if (vector.length() < TINFeatureFactory.EPSILON) { return 0d; } else { Vector2D v = new Vector2D(vector.getX(), vector.getY()); return measureFromNorth(Math.toDegrees(v.angle())); } }
Vector3D vector = new Vector3D(normal.getX(), normal.getY(), 0).normalize();
Vector3D vector = new Vector3D(normal.getX(), normal.getY(), 0).normalize();