Exercises in this lecture   Go to the notes, in which this exercise belongs -- Keyboard shortcut: 'u'   Alphabetic index   Course home   

Exercise solution 4.1
Programmering af klassen Rectangle


Her følger en løsning på opgaven:

/** A clonable Point */
class Point extends java.awt.Point implements Cloneable {
  
  public Object clone(){
    return (super.clone());
  } // end clone

  public Point(int x, int y){
    super(x,y);
  }

}


/** An interval represent an integer interval, from one integer low to another integer high.
    The integer low must be smaller than high */
class Interval implements Cloneable{
  private int from;
  private int to; 

  // invariant: non-empty intervals: from < to
  // invariant: empty intervals: from >= to

  /** Return the lower limit of this interval */
  public int from(){return(from);}

  /** Return the upper limit of this interval*/
  public int to(){return(to);}

  private static Interval emptyInterval = new Interval(1,0);

  /** Construct an interval from its two limits. The lower is the first parameter*/  
  public Interval(int from, int to){
    this.from = from; this.to = to;
  }

  /** Return whether the interval is empty: from() is larger than to(). */
  public boolean empty(){
    return (from >= to);
  }

  /** Return the the overlapping interval of this interval and the parameter interval */
  public Interval overlapInterval (Interval other){
   try{
       if (this.empty() || other.empty() )
          return (Interval)emptyInterval.clone();
       else if (this.from > other.to || this.to < other.from)
          return (Interval)emptyInterval.clone();
       else if (this.from < other.from && other.to < this.to)
          return (Interval)other.clone();
       else if (other.from <= this.from && this.to <= other.to)
          return (Interval)this.clone();
       else if (this.from <= other.from && other.from <= this.to)
          return (new Interval(other.from, this.to));
       else if (other.from <= this.from && this.from <= other.to)
          return (new Interval(this.from, other.to));
       else return null;
      }
   catch (CloneNotSupportedException e){
       return null;
   }
 
  }

  /** Return a string representation of this interval */
  public String toString(){
    if (this.empty() )
     return ("Empty interval");
    else return ("Interval: [" + this.from + ", " + this.to + "]");
  }

}


class Rectangle {
  private Point upperLeft, lowerRight;
    // Invariant: upperLeft.x < lowerRight.x
    //            upperLeft.y > lowerRight.y


  /** Construct a rectangle from an upper left point and a lower right point*/
  public Rectangle(Point upperLeft, Point lowerRight){
    this.upperLeft = (Point)upperLeft.clone();
    this.lowerRight = (Point)lowerRight.clone();
  }

  /** Construct a rectangle from an upper left point an a width and a height*/
  public Rectangle(Point upperLeft, int width, int height){
    this.upperLeft = (Point)upperLeft.clone();
    this.lowerRight = new Point(upperLeft.x + width, upperLeft.y - height);
  }

  /** Construct a rectangle from the coordinates of the upper left and the lower right points*/
  public Rectangle(int ulx, int uly, int lrx, int lry){
    this.upperLeft = new Point(ulx,uly);
    this.lowerRight = new Point(lrx, lry);
  }

  /** Return the width of this rectangle */
  public int width(){
    return(java.lang.Math.abs(upperLeft.x - lowerRight.x));
  }


  /** Return the height of this rectangle */
  public int height(){
    return(java.lang.Math.abs(upperLeft.y - lowerRight.y));
  }

  private Point upperLeft(){
    return new Point(upperLeft.x, upperLeft.y);
  }

  private Point lowerLeft(){
    return new Point(upperLeft.x, upperLeft.y - height());
  }

  private Point lowerRight(){
    return new Point(lowerRight.x, lowerRight.y);
  }

  private Point upperRight(){
    return new Point(lowerRight.x, lowerRight.y + height());
  }

  /* Return the four corner points of this rectangle */
  public Point[] corners(){
    Point[] corners = new Point[4];
    corners[0] = upperLeft();
    corners[1] = lowerLeft();
    corners[2] = lowerRight();
    corners[3] = upperRight();
    return(corners);
  }

  /** Move the rectangle relatively with the two parameters, deltaX and deltaY */
  public void moveRelative (int deltaX, int deltaY) {
    upperLeft.move(upperLeft.x + deltaX,upperLeft.y + deltaY);
    lowerRight.move(lowerRight.x + deltaX,lowerRight.y + deltaY);
  }

  /** Return the rectangle formed by this rectangle and its overlap with the parameter rectangle */
  public Rectangle overlappingRectangle(Rectangle other){
    Interval thisxInterval = new Interval(this.upperLeft().x, this.upperRight().x);
    Interval thisyInterval = new Interval(this.lowerLeft().y, this.upperLeft().y);

    Interval otherxInterval = new Interval(other.upperLeft().x, other.upperRight().x);
    Interval otheryInterval = new Interval(other.lowerLeft().y, other.upperLeft().y);

    Interval xOverlap = thisxInterval.overlapInterval(otherxInterval);
    Interval yOverlap = thisyInterval.overlapInterval(otheryInterval);
    
    if (xOverlap.empty() || yOverlap.empty())
      return (new Rectangle(new Point(0,0), 0, 0)); // empty rectangle returned
    else return (new Rectangle(xOverlap.from(), yOverlap.to(), xOverlap.to(), yOverlap.from()));

  }

  /** Return whether this rectangle is empty */
  public boolean empty(){
    return (width() <= 0 || height() <= 0);
  }

  /** Return a string representation of this rectangle */
  public String toString (){
    return("Rectangle: upper left: " + upperLeft() + "lower right: " + lowerRight());
  }

}


public class RectangleProg{

  public static void main(String[] args){
 
    Rectangle r1 = new Rectangle(5, 10, 7, 6);
    Rectangle r2 = new Rectangle(6, 10, 7, 7);
    Rectangle r3 = new Rectangle(new Point(0,0), 0, 0);

    System.out.println("r1: " + r1);
    System.out.println("r2: " + r2);
    System.out.println("r3: " + r3);
  
    System.out.println("Width of r1: " + r1.width() + "  Height of r1: " + r1.height());
    System.out.println("Width of r2: " + r2.width() + "  Height of r2: " + r2.height());
  
//  r2.moveRelative(3,0);

    System.out.println("r1: " + r1);
    System.out.println("r2: " + r2);

    System.out.println("Overlap: " + r1.overlappingRectangle(r2));

  }

}  

  

Her er endvidere et link til det rene Java program