/** * Computes an average normal vector from a list of polygon coordinates. * Uses Newell's method, which is based * on the fact that the vector with components * equal to the areas of the projection of the polygon onto * the Cartesian axis planes is normal. * * @param seq the sequence of coordinates for the polygon * @return a normal vector */ private Vector3D averageNormal(CoordinateSequence seq) { int n = seq.size(); Coordinate sum = new Coordinate(0,0,0); Coordinate p1 = new Coordinate(0,0,0); Coordinate p2 = new Coordinate(0,0,0); for (int i = 0; i < n - 1; i++) { seq.getCoordinate(i, p1); seq.getCoordinate(i+1, p2); sum.x += (p1.y - p2.y)*(p1.z + p2.z); sum.y += (p1.z - p2.z)*(p1.x + p2.x); sum.z += (p1.x - p2.x)*(p1.y + p2.y); } sum.x /= n; sum.y /= n; sum.z /= n; Vector3D norm = Vector3D.create(sum).normalize(); return norm; }
/** * Get the normal vector to this triangle, of length 1. * @param t input triangle * @return vector normal to the triangle. */ public static Vector3D getNormalVector(Triangle t) throws IllegalArgumentException { if(Double.isNaN(t.p0.z) || Double.isNaN(t.p1.z) || Double.isNaN(t.p2.z)) { throw new IllegalArgumentException("Z is required, cannot compute triangle normal of "+t); } double dx1 = t.p0.x - t.p1.x; double dy1 = t.p0.y - t.p1.y; double dz1 = t.p0.z - t.p1.z; double dx2 = t.p1.x - t.p2.x; double dy2 = t.p1.y - t.p2.y; double dz2 = t.p1.z - t.p2.z; return Vector3D.create(dy1*dz2 - dz1*dy2, dz1 * dx2 - dx1 * dz2, dx1 * dy2 - dy1 * dx2).normalize(); }
/** * Get the normal vector to this triangle, of length 1. * @param t input triangle * @return vector normal to the triangle. */ public static Vector3D getNormalVector(Triangle t) throws IllegalArgumentException { if(Double.isNaN(t.p0.z) || Double.isNaN(t.p1.z) || Double.isNaN(t.p2.z)) { throw new IllegalArgumentException("Z is required, cannot compute triangle normal of "+t); } double dx1 = t.p0.x - t.p1.x; double dy1 = t.p0.y - t.p1.y; double dz1 = t.p0.z - t.p1.z; double dx2 = t.p1.x - t.p2.x; double dy2 = t.p1.y - t.p2.y; double dz2 = t.p1.z - t.p2.z; return Vector3D.create(dy1*dz2 - dz1*dy2, dz1 * dx2 - dx1 * dz2, dx1 * dy2 - dy1 * dx2).normalize(); }
/** * Computes an average normal vector from a list of polygon coordinates. * Uses Newell's method, which is based * on the fact that the vector with components * equal to the areas of the projection of the polygon onto * the Cartesian axis planes is normal. * * @param seq the sequence of coordinates for the polygon * @return a normal vector */ private Vector3D averageNormal(CoordinateSequence seq) { int n = seq.size(); Coordinate sum = new Coordinate(0,0,0); Coordinate p1 = new Coordinate(0,0,0); Coordinate p2 = new Coordinate(0,0,0); for (int i = 0; i < n - 1; i++) { seq.getCoordinate(i, p1); seq.getCoordinate(i+1, p2); sum.x += (p1.y - p2.y)*(p1.z + p2.z); sum.y += (p1.z - p2.z)*(p1.x + p2.x); sum.z += (p1.x - p2.x)*(p1.y + p2.y); } sum.x /= n; sum.y /= n; sum.z /= n; Vector3D norm = Vector3D.create(sum).normalize(); return norm; }
Vector3D vector = new Vector3D(normal.getX(), normal.getY(), 0).normalize(); for(LineSegment side : sides) { Coordinate intersection = CoordinateUtils.vectorIntersection(inCenter, vector, side.p0, new Vector3D(side.p0,side.p1).normalize()); double distInters = intersection == null ? Double.MAX_VALUE : side.distance(intersection); if(intersection != null && distInters < nearestIntersection) {
Vector3D vector = new Vector3D(normal.getX(), normal.getY(), 0).normalize(); for(LineSegment side : sides) { Coordinate intersection = CoordinateUtils.vectorIntersection(inCenter, vector, side.p0, new Vector3D(side.p0,side.p1).normalize()); double distInters = intersection == null ? Double.MAX_VALUE : side.distance(intersection); if(intersection != null && distInters < nearestIntersection) {
/** * 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(); }
/** * 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(); }