/**
   This class describes a line in the plane. 
*/
public class Line
{
   /**
      Constructs a line that is given by two distinct points
      @param x1 the x-coordinate of the first point
      @param y1 the y-coordinate of the first point
      @param x2 the x-coordinate of the second point
      @param y2 the y-coordinate of the second point
   */
   public Line(double x1, double y1, double x2, double y2)
   {
      x = x1;
      y = y1;
      dx = x2 - x1;
      dy = y2 - y1;
      double length = Math.sqrt(dx * dx + dy * dy);
      dx = dx / length;
      dy = dy / length;
   }

   /**
      Returns true if this line is equal to another line.
      @param other another line
      @return true if this line and other are equal
   */
   public double angle(Line other)
   {
      return Math.toDegrees(Math.acos(dx * other.dx + dy * other.dy));
   }

   /**
      Returns true if this line is equal to another line.
      @param other another line
      @return true if this line and other are equal
   */
   public boolean equals(Line other)
   {
      return approxEqual(angle(other), 0) && 
         approxEqual(dx * (other.y - y), dy * (other.x - x));
   }

   /**
      Tests whether two floating-point values are approximately equal.
      @param x a floating-point value
      @param y a floating-point value
      @return true if x and y differ by less than 1E-12
   */
   public boolean approxEqual(double x, double y)
   {
      final double EPSILON = 1E-12;
      return Math.abs(x - y) < EPSILON;
   }

   private double x;
   private double y;
   private double dx;
   private double dy;
}
