package cz.fidentis.analyst.symmetry; import java.io.Serializable; import java.util.List; import javax.vecmath.Point3d; import javax.vecmath.Vector3d; /** * Symmetry plane. * * @author Natalia Bebjakova * @author Dominik Racek */ public class Plane implements Serializable { private Vector3d normal; private double distance; /** * Creates new plane. * * @param a a coordinate * @param b b coordinate * @param c c coordinate * @param d d coordinate */ public Plane(double a, double b, double c, double d) { normal = new Vector3d(a,b,c); distance = d; } /** * Constructor. * @param normal Normal vector of the plane * @param dist distance * @throws IllegalArgumentExpcption if the @code{plane} argument is null */ public Plane(Vector3d normal, double dist) { this(normal.x, normal.y, normal.z, dist); } /** * Copy constructor. * @param plane original plane * @throws IllegalArgumentExpcption if the @code{plane} argument is null */ public Plane(Plane plane) { this(plane.getNormal(), plane.getDistance()); } /** * Creates average plane from existing planes. * * @param planes Source planes * @throws {@code IllegalArgumentException} the {@code planes} list is {@code null} or empty */ public Plane(List<Plane> planes) { if (planes == null || planes.isEmpty()) { throw new IllegalArgumentException("planes"); } Vector3d n = new Vector3d(); double d = 0; Vector3d refDir = planes.get(0).getNormal(); for (int i = 0; i < planes.size(); i++) { Vector3d normDir = planes.get(i).getNormal(); if (normDir.dot(refDir) < 0) { n.sub(normDir); d -= planes.get(i).getDistance(); } else { n.add(normDir); d += planes.get(i).getDistance(); } } setNormal(n); setDistance(d); normalize(); } protected Plane() { } /** * Normalize the plane */ public void normalize() { double normalLength = normal.length(); normal.normalize(); distance /= normalLength; // Do we really want this? --ro } /** * Returns string description of the plane * * @return description of the plane */ @Override public String toString(){ return "APPROXIMATE PLANE:" + System.lineSeparator() + normal.x + System.lineSeparator() + normal.y + System.lineSeparator() + normal.z + System.lineSeparator() + distance + System.lineSeparator(); } public Vector3d getNormal() { return new Vector3d(normal); } public double getDistance() { return distance; } /** * Translate the plane along its normal * * @param value */ public void translate(double value) { this.distance += value; } protected void setNormal(Vector3d normal) { this.normal = normal; } protected void setDistance(double dist) { this.distance = dist; } /** * Calculates an intersection of a plane and a line given by two points * * @param p1 first point of the line * @param p2 second point of the line * @return The point of intersection of null if no point found */ public Point3d getIntersectionWithLine(Point3d p1, Point3d p2) { double distance1 = ((normal.x * p1.x) + (normal.y * p1.y) + (normal.z * p1.z) + distance) / Math.sqrt(normal.x * normal.x + normal.y * normal.y + normal.z * normal.z); double distance2 = ((normal.x * p2.x) + (normal.y * p2.y) + (normal.z * p2.z) + distance) / Math.sqrt(normal.x * normal.x + normal.y * normal.y + normal.z * normal.z); double t = distance1 / (distance1 - distance2); if (distance1 * distance2 > 0) { return null; } Point3d output = new Point3d(p2); output.sub(p1); output.scale(t); output.add(p1); return output; } }