package dwarf.util;
import java.util.Objects;
import dwarf.DwarfException;
/**
* A line is length with out breath nor width, It represents the displacement
* between two points.
*
* <p>
* If a line had any breadth or depth, no matter how small, it would exist in
* more than one dimension; hence a line has neither breadth nor depth and only
* exist in one dimension. A Line is neither a solid nor a surface.</p>
*
* <p>
* If the points share a component in any dimension the line created between
* them can be called straight or right in that dimension, Illustration: If we
* suspend a weight by a string, the string becomes stretched, and we say it is
* straight, by which we mean to express that it has assumed a peculiar definite
* shape. If we mentally abstract from this string all thickness, we obtain the
* notion of the simplest of all lines, which we call a straight line.</p>
*
* @author Matthew 'siD' Van der Bijl
*
* @see dwarf.util.Point
* @see java.lang.Object
* @see java.lang.Cloneable
*/
public class Line extends java.lang.Object implements Cloneable {
/**
* The start point of the <code>Line</code>.
*/
private Point A;
/**
* The end point of the <code>Line</code>.
*/
private Point B;
/**
* Default constructor.
*/
public Line() {
this(null, null);
}
public Line(Point A, Point B) {
super();
this.A = A;
this.B = B;
}
public Line(Line l) {
this(l.getA(), l.getB());
}
/**
* Create a new line based on two points.
*
* @param x1 The x coordinate of the start point
* @param y1 The y coordinate of the start point
* @param x2 The x coordinate of the end point
* @param y2 The y coordinate of the end point
*/
public Line(float x1, float y1, float x2, float y2) {
this(new Point2D(x1, y1), new Point2D(x2, y2));
}
public Point getA() {
return this.A;
}
public void setA(Point A) {
this.A = A;
}
public Point getB() {
return this.B;
}
public void setB(Point B) {
this.B = B;
}
public Line get() {
return this;
}
public void set(Point A, Point B) {
this.A = A;
this.B = B;
}
public void set(Line l) {
this.A = l.getA();
this.B = l.getB();
}
public Point midpoint() {
double[] result;
if (A.getNumDimensions() >= B.getNumDimensions()) {
result = new double[A.getNumDimensions()];
} else {
result = new double[B.getNumDimensions()];
}
for (int i = 0; i < result.length; i++) {
double a;
double b;
try {
a = A.getComponent(i);
} catch (ArrayIndexOutOfBoundsException outOfBoundsException) {
a = 0;
}
try {
b = B.getComponent(i);
} catch (ArrayIndexOutOfBoundsException outOfBoundsException) {
b = 0;
}
result[i] = (a + b) / 2;
}
return new Point(result);
}
public double lengthSq() {
double result = 0;
int cnt;
if (A.getNumDimensions() >= B.getNumDimensions()) {
cnt = A.getNumDimensions();
} else {
cnt = B.getNumDimensions();
}
for (int i = 0; i < cnt; i++) {
double a;
double b;
try {
a = A.getComponent(i);
} catch (ArrayIndexOutOfBoundsException outOfBoundsException) {
a = 0;
}
try {
b = B.getComponent(i);
} catch (ArrayIndexOutOfBoundsException outOfBoundsException) {
b = 0;
}
result += (a - b) * (a - b);
}
return result;
}
public double length() {
return java.lang.Math.sqrt(this.lengthSq());
}
@Override
public int hashCode() {
int hash = 7;
hash = 19 * hash + Objects.hashCode(A);
hash = 19 * hash + Objects.hashCode(B);
return hash;
}
/**
* Returns true if the <code>this</code> is equal to the argument and false
* otherwise. Consequently, if both argument are null, true is returned,
* false is returned. Otherwise, equality is determined by using the equals
* method of the first argument.
*
* @param obj the <code>Object</code> to be tested
* @see java.lang.Object#equals(java.lang.Object)
*
* @return true if the argument is equal to <code>this</code> other and
* false otherwise
*/
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
} else if (getClass() != obj.getClass()) {
return false;
}
final Line other = (Line) obj;
if (!Objects.equals(this.getA(), other.getA())) {
return false;
} else if (!Objects.equals(this.getB(), other.getB())) {
return false;
}
return true;
}
/**
* Returns a string representation of the object.
* <p>
* In general, the toString method returns a string that "textually
* represents" this object. The result should be a concise but informative
* representation that is easy for a person to read. It is recommended that
* all subclasses override this method.</p>
*
* @return a textually representation of this object
*/
@Override
public String toString() {
return "Line[" + A + ", " + B + "]";
}
@Override
protected Line clone() throws CloneNotSupportedException {
return new Line(this);
}
public void translate(double delta) {
A.translate(delta);
B.translate(delta);
}
public void translate(int index, double delta) throws DwarfException {
try {
A.translate(index, delta);
B.translate(index, delta);
} catch (ArrayIndexOutOfBoundsException outOfBoundsException) {
throw new DwarfException(outOfBoundsException);
}
}
}