/** * Get the vector with the highest down slope in the plan associated to this triangle. * * @return return the steepest vector. * @throws DelaunayError */ public final DPoint getSteepestVector() throws DelaunayError { DPoint normal = getNormalVector(); if (Math.abs(normal.getX()) < Tools.EPSILON && Math.abs(normal.getY()) < Tools.EPSILON) { return new DPoint(0, 0, 0); } DPoint pente; if (Math.abs(normal.getX()) < Tools.EPSILON) { pente = new DPoint(0, 1, -normal.getY() / normal.getZ()); } else if (Math.abs(normal.getY()) < Tools.EPSILON) { pente = new DPoint(1, 0, -normal.getX() / normal.getZ()); } else { pente = new DPoint( 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 (pente.getZ() > Tools.EPSILON) { pente.setX(-pente.getX()); pente.setY(-pente.getY()); pente.setZ(-pente.getZ()); } // We normalize it double length = Math.sqrt(pente.squareDistance(new DPoint(0, 0, 0))); if (length > Tools.EPSILON) { pente.setX(pente.getX() / length); pente.setY(pente.getY() / length); pente.setZ(pente.getZ() / length); } return pente; }
/** * Get the normal vector to this triangle, of length 1. * * @return Get the vector normal to the triangle. * @throws DelaunayError */ public final DPoint getNormalVector() throws DelaunayError { // We first perform a vectorial product between two of the edges double dx1 = edges[0].getStartPoint().getX() - edges[0].getEndPoint().getX(); double dy1 = edges[0].getStartPoint().getY() - edges[0].getEndPoint().getY(); double dz1 = edges[0].getStartPoint().getZ() - edges[0].getEndPoint().getZ(); double dx2 = edges[1].getStartPoint().getX() - edges[1].getEndPoint().getX(); double dy2 = edges[1].getStartPoint().getY() - edges[1].getEndPoint().getY(); double dz2 = edges[1].getStartPoint().getZ() - edges[1].getEndPoint().getZ(); DPoint vec = new DPoint(dy1 * dz2 - dz1 * dy2, dz1 * dx2 - dx1 * dz2, dx1 * dy2 - dy1 * dx2); double length = Math.sqrt(vec.squareDistance(new DPoint(0, 0, 0))); vec.setX(vec.getX() / length); vec.setY(vec.getY() / length); vec.setZ(vec.getZ() / length); return vec; }
/** * Compute the intersection point according to the vector opposite to the steepest vector. If dp * is outside the triangle, we return null. * * @param dp * @return The point pt of the triangle's boundary for which (dp pt) is colinear to the steepest * vector. * @throws DelaunayError */ public final DPoint getCounterSteepestIntersection(DPoint dp) throws DelaunayError { if (isInside(dp) || isOnAnEdge(dp)) { for (DEdge ed : edges) { if (!isTopoOrientedToEdge(ed)) { DPoint counterSteep = getSteepestVector(); counterSteep.setX(-counterSteep.getX()); counterSteep.setY(-counterSteep.getY()); counterSteep.setZ(-counterSteep.getZ()); DPoint pt = Tools.computeIntersection( ed.getStartPoint(), ed.getDirectionVector(), dp, counterSteep); if (ed.contains(pt)) { return pt; } } } } return null; }
/** * Compute the azimut of the triangle in degrees between north and steeepest vector. Aspect is * measured clockwise in degrees from 0, due north, to 360, again due north, coming full circle. * * @return the aspect of the slope of this triangle. * @throws DelaunayError */ public final double getSlopeAspect() throws DelaunayError { double orientationPente; DPoint c1 = new DPoint(0.0, 0.0, 0.0); DPoint c2 = getSteepestVector(); if (c2.getZ() > 0.0) { c2.setX(-c2.getX()); c2.setY(-c2.getY()); c2.setZ(-c2.getZ()); } // l'ordre des coordonnees correspond a l'orientation de l'arc // "sommet haut vers sommet bas" double angleAxeXrad = Tools.angle(c1, c2); // on considere que l'axe nord correspond a l'axe Y positif double angleAxeNordrad = Tools.PI_OVER_2 - angleAxeXrad; double angleAxeNorddeg = Math.toDegrees(angleAxeNordrad); // on renvoie toujours une valeur d'angle >= 0 orientationPente = angleAxeNorddeg < 0.0 ? 360.0 + angleAxeNorddeg : angleAxeNorddeg; return orientationPente; }