// Guide to Java
// Copyright 2014, by J.T. Streib and T. Soma


// a program to create lines and points, and output the
// information on them

public class Lines {                                  
 public static void main(String[] args) {          
    // declaration and initialization of variables   
    PointD pt1, pt2;
    LineSI line1, line2, line3, line4, line5, line6;
    pt1 = new PointD(1.0, 4.0);
    pt2 = new PointD(-3.0, 2.0);
    line1 = new LineSI(pt1, pt2);                // See Exercise 4
    line2 = new LineSI(line1);
    line3 = new LineSI(1.0, 2.0, 4.0, -1.0);
    line4 = new LineSI(0.5, 3.5);
    line5 = new LineSI();
    line6 = new LineSI(2.0);
      
    // output the information of lines
    System.out.println("line1: slope = " + line1.getSlope()
                  + ", intercept = " + line1.getIntercept());
    System.out.println("line2: slope = " + line2.getSlope()
                  + ", intercept = " + line2.getIntercept());
    System.out.println("line3: slope = " + line3.getSlope()
                  + ", intercept = " + line3.getIntercept());
    System.out.println("line4: slope = " + line4.getSlope()
                  + ", intercept = " + line4.getIntercept());
    System.out.println("line5: slope = " + line5.getSlope()
                  + ", intercept = " + line5.getIntercept());
    System.out.println("line6: slope = " + line6.getSlope()
                  + ", intercept = " + line6.getIntercept());
                        
    // output the result from compareLines method
    if (line1.compareLines(line2))
       System.out.println("line1 and line2 are the same.");
    else
       System.out.println("line1 and line2 are not the same.");
          
    // output the result from compareLines method
    if (line4.compareLines(line5))
       System.out.println("line4 and line5 are the same.");
    else
       System.out.println("line4 and line5 are not the same.");
          
    // output the result from distance method
    System.out.printf("The distance between line3 and pt1 is "
                   + "%.2f.", line3.distance(pt1));
    System.out.println();
                        
    // output the result from distance method
    System.out.printf("The distance between line6 and pt2 is "
                    + "%.2f.", line6.distance(pt2));
    System.out.println();
 }
}

// definition of LineSI class

public class LineSI {
 // data members
 private static final double DEFAULT_VALUE = 0.0;
 private double slope;
 private double intercept;
  
 // constructors
 public LineSI() {
    // using fourth constructor
    this(DEFAULT_VALUE, DEFAULT_VALUE);
 }
  
 public LineSI(double slope) {
    // using fourth constructor
    this(slope, DEFAULT_VALUE);
 }

 public LineSI(LineSI line) {
    // using fourth constructor
    this(line.slope, line.intercept);
 }

 public LineSI(double slope, double intercept) {
    // using first setLine method
    setLine(slope, intercept);
 }
  
 public LineSI(PointD pt1, PointD pt2) {
    // using second setLine method
    setLine(pt1, pt2);
 }

 public LineSI(double x1, double y1, double x2, double y2) {
    // using third setLine method
    setLine(x1, y1, x2, y2);
 }
  
 // methods
 public void setSlope(double slope) {
    this.slope = slope;    
 }
  
 public void setIntercept(double intercept) {
    this.intercept = intercept;    
 }
  
 public void setLine(double slope, double intercept) {
    // using setSlope and setIntercept methods
    setSlope(slope);
    setIntercept(intercept);
 }

 public void setLine(PointD pt1, PointD pt2) {
    // using first setLine method
    setLine((pt2.getY()-pt1.getY()) / (pt2.getX()-pt1.getX()),
            ((pt2.getX()*pt1.getY()) -
            (pt1.getX()*pt2.getY()))/(pt2.getX()-pt1.getX()));
  }

 public void setLine(double x1,double y1,double x2,double y2) {
    // using first setLine method
    setLine((y2-y1) / (x2-x1),
            ((x2*y1) - (x1*y2)) / (x2-x1));
 }
  
 public double getSlope() {
    return slope;   
 }
  
 public double getIntercept() {
    return intercept;   
 }
  
 public boolean compareLines(LineSI line) {
    boolean flag;
    flag = false;
    if (slope == line.slope && intercept == line.intercept)
       flag = true;
    return flag;
 }
  
 public double distance(PointD pt) {
    return Math.abs(slope*pt.getX() - pt.getY() +
           intercept) / Math.sqrt(Math.pow(slope, 2) + 1 );
 }
}

// definition of PointD class

class PointD {
 // data members
 private double x, y;
 
 // constructors
 public PointD() {
    this(0.0,0.0);
 }   
 
 public PointD(double x, double y) {
    this.x = x;
    this.y = y;
 }

 public PointD(PointD p) {
    this(p.getX(),p.getY());
 }

 // methods
 public void setX(double x) {
    this.x = x;
 }
 
 public void setY(double y) {
    this.y = y;
 }

 public double getX() {
    return x;
 }
 
 public double getY() {
    return y;
 }
 
 public double distance() {
    double dist;
    dist=Math.sqrt(Math.pow(x,2)+ Math.pow(y,2));
    return dist;
 }                                                        

 public double distance(PointD p) {                       
    double dist;                                          
    dist=Math.sqrt(Math.pow(x-p.getX(),2)                 
         + Math.pow(y-p.getY(),2));                       
    return dist;                                          
 }       
 
 public PointD midPoint(PointD p) {                      
    PointD mid;                                           
    mid = new PointD();                                   
    mid.setX( (x+p.getX()) / 2 );                         
    mid.setY( (y+p.getY()) / 2 );                         
    return mid;                                           
 }                                                        
}