# Simplifying data-type implementation for axis-aligned rectangles using data-type implementation for closed intervals

This is exercise 3.2.8. from the book Computer Science An Interdisciplinary Approach by Sedgewick & Wayne:

Write a data type Interval that implements the following API:

An interval is defined to be the set of all points on the line greater than or equal to min and less than or equal to max.

This is exercise 3.2.10. from the book Computer Science An Interdisciplinary Approach by Sedgewick & Wayne:

Develop an implementation of your Rectangle API from exercise 3.2.1 that takes advantage of the Interval data type to simplify and clarify the code.

And so this post is kind of a follow-up to my previous post.

Here are my programs:

public class Interval {
private final double min;
private final double max;

public Interval(double min, double max) {
this.min = min;
this.max = max;
}
public double getMin() {
return min;
}
public double getMax() {
return max;
}
public boolean contains(double x) {
if (x == min) return true;
else if (x == max) return true;
else if (x > min && x < max) return true;
else return false;
}
public boolean intersects(Interval otherInterval) {
double otherMin = otherInterval.getMin();
double otherMax = otherInterval.getMax();
if (otherMin > min && otherMin < max) return true;
else if (otherMax > min && otherMax < max) return true;
else if (min > otherMin && min < otherMax) return true;
else if (max > otherMin && max < otherMax) return true;
else if (otherMin == max) return true;
else if (otherMax == min) return true;
else return false;
}
public String toString() {
return "[" + min + "," + max + "]";
}
public static void main(String[] args) {
double min1 = Double.parseDouble(args[0]);
double max1 = Double.parseDouble(args[1]);
double min2 = Double.parseDouble(args[2]);
double max2 = Double.parseDouble(args[3]);
Interval interval1 = new Interval(min1, max1);
Interval interval2 = new Interval(min2, max2);
System.out.println(interval1.toString());
System.out.println(interval2.toString());
System.out.println(interval1.intersects(interval2));
}
}


public class Rectangle {
private final double x;
private final double y;
private final double width;
private final double height;

public Rectangle(double x, double y, double width, double height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public double getLeft() {
return x - width / 2;
}
public double getRight() {
return x + width / 2;
}
public double getBottom() {
return y - height / 2;
}
public double getTop() {
return y + height / 2;
}
public double calculateArea() {
return width * height;
}
public double calculatePerimeter() {
return 2 * width + 2 * height;
}
public boolean contains(Rectangle otherRectangle) {
if (getLeft() <= otherRectangle.getLeft() &&
getRight() >= otherRectangle.getRight() &&
getBottom() <= otherRectangle.getBottom() &&
getTop() >= otherRectangle.getTop()) {
return true;
} else return false;
}
public boolean intersects(Rectangle otherRectangle) {
Interval leftToRight = new Interval(getLeft(), getRight());
Interval bottomToTop = new Interval(getBottom(), getTop());
Interval otherLeftToRight = new Interval(otherRectangle.getLeft(), otherRectangle.getRight());
Interval otherBottomToTop = new Interval(otherRectangle.getBottom(), otherRectangle.getTop());
if (leftToRight.intersects(otherLeftToRight) && bottomToTop.intersects(otherBottomToTop)) return true;
else if (contains(otherRectangle)) return true;
else return false;
}
public void draw() {
StdDraw.rectangle(x, y, width / 2, height / 2);
}
public static double randomize(double a, double b) {
return a + Math.random() * (b - a);
}
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
double min = Double.parseDouble(args[1]);
double max = Double.parseDouble(args[2]);
Rectangle[] rectangles = new Rectangle[n];
for (int i = 0; i < n; i++) {
rectangles[i] = new Rectangle(randomize(0.2, 0.8),
randomize(0.2, 0.8),
randomize(min, max),
randomize(min, max));
}
for (int i = 0; i < n; i++) {
rectangles[i].draw();
}
double averageArea = 0;
double averagePerimeter = 0;
for (int i = 0; i < n; i++) {
averageArea += rectangles[i].calculateArea();
averagePerimeter += rectangles[i].calculatePerimeter();
}
System.out.println("Average area = " + averageArea);
System.out.println("Average perimeter = " + averagePerimeter);
int[] intersections = new int[n];
int sumOfIntersections = 0;
for (int i = 0; i < n; i++) {
intersections[i]--;
for (int j = 0; j < n; j++) {
if (rectangles[i].intersects(rectangles[j])) {
intersections[i]++;
}
}
sumOfIntersections += intersections[i];
}
System.out.println("Average intersections = " + ((int) sumOfIntersections / n));
}
}


And the above Rectangle class is an improved version of the previous one. StdDraw is a simple API written by the authors of the book. I checked my program and it works.

Is there any way that I can improve my programs?

• The assignment does not mention getMin() and getMax() interfaces. I'd rather would not implement them at all; in any case they shall not be public.

• There is no need to special case x == min and x == max in Interval.contains. A single line

  return x >= min && x <= max;


does the job.

• Interval.intersects logic is very complicated (and suffers the same special-casing problem). It can be greatly simplified into another single line:

  return max >= other.min && min <= other.max;

• I don't see how Rectangle takes advantage of Interval.

• @Emma No I didn't ( -_* ). I just didn't review the second portion at all - it doesn't comply with the assignment requirements.
– vnp
Sep 16, 2020 at 19:44
• Thank you very much. Interval simplifies the intersects method within Rectangle (the one I wrote previously without using interval was too complicated). Sep 16, 2020 at 20:45
• @KhashayarBaghizadeh It does not. The assignment calls for class Rectangle { private final Interval horizontal; private final Interval vertical; .... } and using the Interval methods directly under the hood.
– vnp
Sep 16, 2020 at 20:50
• Oh! I get it now. I cannot thank you enough for elucidating this. Sep 16, 2020 at 21:00