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 }