001 package physics3d; 002 003 public strictfp class Line { 004 private final Vect3 direction; 005 006 private final Vect3 pointOnLine; 007 008 // Rep. Invariant: 009 // direction != null && 010 // pointOnLine != null && 011 // direction.rho() == 1.0 012 013 // Abstraction Function: 014 // The Line with a direction 'direction' and a point on the plane 015 // 'pointOnLine' 016 017 /** 018 * @requires <code>direction</code> is not null, <code>pointOnLine</code> 019 * is not null, 020 * @effects constructs a Line 021 */ 022 public Line(Vect3 direction, Vect3 pointOnLine) { 023 this.direction = direction.unitSize(); 024 this.pointOnLine = pointOnLine; 025 // checkRep(); 026 } 027 028 /** 029 * @requires p1, p2 != null !p1.equals(p2) 030 * @return the line that contains these two points 031 */ 032 public static Line MakeLineFromTwoPoints(Vect3 p1, Vect3 p2) { 033 return new Line(p1.minus(p2).unitSize(), p1); 034 } 035 036 @SuppressWarnings("unused") 037 private void checkRep() { 038 if (direction == null || pointOnLine == null || direction.rho() != 1.0) { 039 throw new RuntimeException(); 040 } 041 } 042 043 /** 044 * @return the direction of <code>this</code> 045 */ 046 public Vect3 getDirection() { 047 // checkRep(); 048 return direction; 049 } 050 051 /** 052 * @return a point on <code>this</code> 053 */ 054 public Vect3 getPointOnLine() { 055 // checkRep(); 056 return pointOnLine; 057 } 058 059 /** 060 * @requires v != null 061 * @return true if v is within <code>GameConstants.TOLERANCE</code> of 062 * <code>this</code> 063 */ 064 public boolean containsPoint(Vect3 v) { 065 if (getPointOnLineClosestToP(v).isAbout(v)) { 066 return true; 067 } 068 return false; 069 } 070 071 /** 072 * @requires v != null 073 * @return the point on <code>this</code> such that 074 * v.minus(p).cross(direction) = <code>Vect3.ZERO</code> 075 */ 076 public Vect3 getPointOnLineClosestToP(Vect3 p) { 077 // checkRep(); 078 Vect3 obliqueVect = p.minus(this.pointOnLine); 079 if (this.direction.rho() == 0) { 080 return this.pointOnLine; 081 } 082 Vect3 parallelVect = obliqueVect.projectOnToB(this.direction); 083 Vect3 perpVect = obliqueVect.minus(parallelVect); 084 return p.minus(perpVect); 085 } 086 }