/**
*
*/
package cz.cuni.mff.peckam.java.origamist.math;
import static cz.cuni.mff.peckam.java.origamist.math.MathHelper.EPSILON;
import static java.lang.Math.abs;
import javax.vecmath.Point2d;
/**
* Represents a half-plane in 2D.
*
* @author Martin Pecka
*/
public class HalfPlane2d implements Cloneable
{
/**
* This is a coefficient in the general equation of the defining line (ax + by + c = 0). The halfplane is defined as
* the set of points [x,y] for which is ax + by + c >= 0 true.
*/
protected double a = 0;
/**
* This is a coefficient in the general equation of the defining line (ax + by + c = 0). The halfplane is defined as
* the set of points [x,y] for which is ax + by + c >= 0 true.
*/
protected double b = 0;
/**
* This is a coefficient in the general equation of the defining line (ax + by + c = 0). The halfplane is defined as
* the set of points [x,y] for which is ax + by + c >= 0 true.
*/
protected double c = 0;
/** The border line. */
protected Line2d line;
/** A general point inside the halfplane. */
protected Point2d r;
/**
* Constructs the halfplane in the following manner - p1,p2 define a line and r is a general point in the halfplane.
*
* @param p1 First point of the defining line.
* @param p2 Second point of the defining line.
* @param r A general point in the halfplane.
*
* @throws IllegalArgumentException If r lies on the line defined by p1 and p2.
*/
public HalfPlane2d(Point2d p1, Point2d p2, Point2d r) throws IllegalArgumentException
{
a = p1.y - p2.y;
b = p2.x - p1.x;
c = p1.x * p2.y - p1.y * p2.x;
line = new Line2d(p1, p2);
this.r = r;
if (line.contains(r)) {
throw new IllegalArgumentException(
"Trying to define a halfplane but the general point lies on the border line.");
}
if (!contains(r)) {
a = -a;
b = -b;
c = -c;
line = new Line2d(p2, p1);
}
}
/**
* Constructs the halfplane in the following manner - p1,p2 define a line and r is a general point in the halfplane.
*
* @param p1x x-coordinate of the first point of the defining line.
* @param p1y y-coordinate of the first point of the defining line.
* @param p2x x-coordinate of the second point of the defining line.
* @param p2y y-coordinate of the second point of the defining line.
* @param rx x-coordinate of a general point in the halfplane.
* @param ry y-coordinate of a general point in the halfplane.
*
* @throws IllegalArgumentException If r lies on the line defined by p1 and p2.
*/
public HalfPlane2d(double p1x, double p1y, double p2x, double p2y, double rx, double ry)
throws IllegalArgumentException
{
this(new Point2d(p1x, p1y), new Point2d(p2x, p2y), new Point2d(rx, ry));
}
/**
* @return The border line on this halfplane.
*/
public Line2d getLine()
{
return line;
}
/**
* Returns true if this halfplane contains the given point.
*
* @param p The point to check.
* @return Whether the given point lies in this halfplane.
*/
public boolean contains(Point2d p)
{
return p.x * a + p.y * b + c >= 0 - EPSILON;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(a);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(b);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(c);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
HalfPlane2d other = (HalfPlane2d) obj;
if (Double.doubleToLongBits(a) != Double.doubleToLongBits(other.a))
return false;
if (Double.doubleToLongBits(b) != Double.doubleToLongBits(other.b))
return false;
if (Double.doubleToLongBits(c) != Double.doubleToLongBits(other.c))
return false;
return true;
}
/**
* Return <code>true</code> if the given halfplane is almost equal to this one.
*
* @param other The halfplane to compare.
* @return <code>true</code> if the given halfplane is almost equal to this one.
*/
public boolean epsilonEquals(HalfPlane2d other)
{
if (other == null)
return false;
return abs(a - other.a) < EPSILON && abs(b - other.b) < EPSILON && abs(c - other.c) < EPSILON;
}
@Override
public String toString()
{
return "HalfPlane2d [" + a + "x + " + b + "y + " + c + " >= 0]";
}
@Override
protected HalfPlane2d clone() throws CloneNotSupportedException
{
return new HalfPlane2d(null, null, null);
}
}