001 package physics3d;
002
003 public strictfp class Plane {
004 private final Vect3 normal;
005
006 private final Vect3 pointOnPlane;
007
008 // Rep. Invariant:
009 // normal != null &&
010 // pointOnPlane != null &&
011 // normal.rho() == 1.0
012
013 // Abstraction Function:
014 // The plane with a normal 'normal' and a point on the plane
015 // 'pointOnPlane'
016
017 /**
018 * @requires <code>normal</code> is not null, <code>pointOnPlane</code> is
019 * not null, <code>normal.rho()</code> != 0,
020 * @effects constructs a plane
021 */
022 public Plane(Vect3 normal, Vect3 pointOnPlane) {
023 this.normal = normal.unitSize();
024 this.pointOnPlane = pointOnPlane;
025 }
026
027 /**
028 * @requires p1, p2, p3 != null p1, p2, p3 are distinct and not collinear
029 * @return the plane that contains these three points
030 */
031 public static Plane MakePlaneFromThreePoints(Vect3 p1, Vect3 p2, Vect3 p3) {
032 return new Plane(p2.minus(p1).cross(p3.minus(p1)), p1);
033 }
034
035 @SuppressWarnings("unused")
036 private void checkRep() {
037 if (normal == null || pointOnPlane == null || normal.rho() != 1.0) {
038 throw new RuntimeException();
039 }
040 }
041
042 /**
043 * @requires pointOffPlane != null
044 * @return the point p such that p is on this and
045 * p.minus(pointOffPlane).cross(normal) = <code>Vect3.Zero </code>
046 */
047 public Vect3 perpVectorFromPlaneToPoint(Vect3 pointOffPlane) {
048 // checkRep();
049 Vect3 obliqueVector = pointOffPlane.minus(pointOnPlane);
050 return obliqueVector.projectOnToB(normal);
051 }
052
053 /**
054 * @requires pointOffPlane != null
055 * @return the perpendicular distance from pointOffPlane to <code>this</code>
056 */
057 public double perpDistanceFromPlaneToPoint(Vect3 pointOffPlane) {
058 // checkRep();
059 Vect3 obliqueVector = pointOffPlane.minus(pointOnPlane);
060 return obliqueVector.projectOnToB(normal).rho();
061 }
062
063 /**
064 * @return a unit vector perpendicular to <code>this</code>
065 */
066 public Vect3 getNormal() {
067 // checkRep();
068 return normal;
069 }
070
071 /**
072 * @return a point on the plane
073 */
074 public Vect3 getPointOnPlane() {
075 // checkRep();
076 return pointOnPlane;
077 }
078
079 /**
080 * @requires v != null
081 * @return true if the distance from v to this is less than
082 * GameConstants.TOLERANCE
083 */
084 public boolean containsPoint(Vect3 v) {
085 return Vect3.isAbout(perpDistanceFromPlaneToPoint(v), 0);
086 }
087 }