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 }