Monday 19 December 2016

Chapter 13 Exercise 5, Introduction to Java Programming, Tenth Edition Y. Daniel LiangY.

13.5 (Enable GeometricObject comparable)
Modify the GeometricObject class to implement the Comparable interface,
and define a static max method in the GeometricObject class for finding
the larger of two GeometricObject objects. Draw the UML diagram and implement
the new GeometricObject class. Write a test program that uses the max method
to find the larger of two circles and the larger of two rectangles.

import javafx.scene.shape.Rectangle;
public class MyRectangle2D extends GeometricObject {

    private static final int X = 0;
    private static final int Y = 1;

    public double centerX;
    public double centerY;

    public double width;
    public double height;

    public MyRectangle2D(double centerX, double centerY, double width, double height) {
        this.centerX = centerX;
        this.centerY = centerY;
        this.width = width;
        this.height = height;
    }

    public MyRectangle2D(MyPoint centerPoint, double width, double height) {
        this(centerPoint.x, centerPoint.y, width, height);
    }

    public MyRectangle2D(Rectangle rectangle) {
        this(rectangle.getX(), rectangle.getY(), rectangle.getWidth(), rectangle.getHeight());
    }

    public MyRectangle2D() {
        this(0, 0, 1, 1);
    }

    public MyPoint getCenterP() {
        return new MyPoint(centerX, centerY);
    }
    public MyPoint getP1() {
        return new MyPoint(centerX - width / 2, centerY + height / 2);
    }

    public MyPoint getP2() {
        return new MyPoint(centerX + width / 2, centerY + height / 2);
    }

    public MyPoint getP3() {
        return new MyPoint(centerX - width / 2, centerY - height / 2);
    }

    public MyPoint getP4() {
        return new MyPoint(centerX + width / 2, centerY - height / 2);
    }

    public double getCenterX() {
        return centerX;
    }

    public void setCenterX(double centerX) {
        this.centerX = centerX;
    }

    public double getCenterY() {
        return centerY;
    }

    public void setCenterY(double centerY) {
        this.centerY = centerY;
    }

    public double getWidth() {
        return width;
    }

    public void setWidth(double width) {
        this.width = width;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    /** returns the perimeter of the rectangle. **/
    @Override
    public double getPerimeter() {

        return width * 2 + height * 2;
    }

    /** returns the area of the rectangle **/
    @Override
    public double getArea() {
        return width * height;
    }

    public boolean contains(double x, double y) {

        // Get max X & Y
        double maxX = getMax(getP1().x, getP2().x, getP3().x, getP4().x);
        double maxY = getMax(getP1().y, getP2().y, getP3().y, getP4().y);
        // Get min X & Y
        double minX = getMin(getP1().x, getP2().x, getP3().x, getP4().x);
        double minY = getMin(getP1().y, getP2().y, getP3().y, getP4().y);

        if (x < minX || x > maxX || y < minY || y > maxY)  return false;

        return true;

    }

    public boolean contains(MyRectangle2D r2) {
        double xDistance = (r2.centerX > centerX) ? r2.centerX - centerX : centerX - r2.centerX;
        double yDistance = (r2.centerY > centerY) ? r2.centerY - centerY : centerY - r2.centerY;

        // if the r2 is inside this rectangle
        // this is only valid if the rectangles are parallel
        return (xDistance <= (width - r2.width) / 2 && yDistance <= (height - r2.height) / 2);

    }

    public boolean overlaps(MyRectangle2D r2) {
        // subtract from the highest number
        double xDistance = (r2.centerX > centerX) ? r2.centerX - centerX : centerX - r2.centerX;
        double yDistance = (r2.centerY > centerY) ? r2.centerY - centerY : centerY - r2.centerY;

        // if the r2 overlaps this rectangle
        // this is only valid if the rectangles are parallel
        return (xDistance <= (width + r2.width) / 2 && yDistance <= (height + r2.height) / 2);

    }

    public static boolean r1OverLapsR2(Rectangle r1, Rectangle r2) {
        return r1.intersects(r2.getBoundsInLocal()) || r2.intersects(r1.getBoundsInLocal());
    }

    public javafx.scene.shape.Rectangle getRectangle() {
        return new Rectangle(centerX, centerY, width, height);
    }
    public boolean contains(MyPoint[] points) {

        for (MyPoint p : points) {
            if (!contains(p)) return false;
        }
        return true;
    }

    public boolean contains(MyPoint point) {
        return contains(point.x, point.y);
    }

    public static MyRectangle2D getRectangle(double[][] points) {

        // find leftLowestPoint

        // find rightMostPoint

        // find the center from highest and lowest point

        // x distance = width

        // y distance = height
        MyPoint[] myPoints = new MyPoint[points.length];
        for (int i = 0; i < points.length; i++) {
            myPoints[i] = new MyPoint(points[i][0], points[i][1]);
        }

        return getRectangle(myPoints);
    }

    public static MyRectangle2D getRectangle(MyPoint[] points) {

        MyPoint leftMost = getLeftMostPoint(points);
        MyPoint rightMost = getRighMostPoint(points);
        double width = Math.abs(rightMost.x - leftMost.x);

        MyPoint highest = getHighestPoint(points);
        MyPoint lowest = getLowestPoint(points);
        double height = Math.abs(highest.y - lowest.y);

        double centerX = highest.getCenterPoint(lowest).x;
        double centerY = leftMost.getCenterPoint(rightMost).y;

        return new MyRectangle2D(centerX, centerY, width, height);
    }

    private static MyPoint getLeftMostPoint(MyPoint[] points) {

        MyPoint leftMost = points[0];
        for (int i = 0; i < points.length; i++) {
            if (leftMost.x > points[i].x) {
                leftMost = points[i];
            }
        }
        return leftMost;
    }

    private static MyPoint getRighMostPoint(MyPoint[] points) {

        MyPoint rightMost = points[0];
        for (int i = 0; i < points.length; i++) {
            if (rightMost.x < points[i].x) {
                rightMost = points[i];
            }
        }
        return rightMost;
    }

    private static MyPoint getHighestPoint(MyPoint[] points) {

        MyPoint highest = points[0];
        for (int i = 0; i < points.length; i++) {
            if (highest.y < points[i].y) {
                highest = points[i];
            }
        }
        return highest;
    }

    private static MyPoint getLowestPoint(MyPoint[] points) {

        MyPoint lowest = points[0];
        for (int i = 0; i < points.length; i++) {
            if (lowest.y > points[i].y) {
                lowest = points[i];
            }
        }
        return lowest;
    }

    private double getMax(double... n) {
        double max = n[0];
        for (int i = 1; i < n.length; i++) {
            if (max < n[i]) {
                max = n[i];
            }
        }
        return max;
    }
    private double getMin(double... n) {
        double min = n[0];
        for (int i = 1; i < n.length; i++) {
            if (min > n[i]) {
                min = n[i];
            }
        }
        return min;
    }

    @Override
    public String toString() {
        return "MyRectangle2D{" +
                "centerX=" + centerX +
                ", centerY=" + centerY +
                ", width=" + width +
                ", height=" + height +
                '}';
    }
}

public abstract class GeometricObject implements Comparable<GeometricObject> {
    private String color = "white";
    private boolean filled;
    private java.util.Date dateCreated;

    /** Construct a default geometric object */
    protected GeometricObject() {
        dateCreated = new java.util.Date();
    }

    /** Construct a geometric object with color and filled value */
    protected GeometricObject(String color, boolean filled) {
        dateCreated = new java.util.Date();
        this.color = color;
        this.filled = filled;
    }

    /** Return color */
    public String getColor() {
        return color;
    }

    /** Set a new color */
    public void setColor(String color) {
        this.color = color;
    }

    /** Return filled. Since filled is boolean,
     *  the get method is named isFilled */
    public boolean isFilled() {
        return filled;
    }

    /** Set a new filled */
    public void setFilled(boolean filled) {
        this.filled = filled;
    }

    /** Get dateCreated */
    public java.util.Date getDateCreated() {
        return dateCreated;
    }

    /** Return a string representation of this object */
    @Override
    public String toString() {
        return "created on " + dateCreated + "\ncolor: " + color +
                " and filled: " + filled;
    }

    @Override
    public int compareTo(GeometricObject o) {
        if (getArea() > o.getArea())
            return 1;
        else if (getArea() < o.getArea())
            return -1;
        else
            return 0;
    }

    public static GeometricObject max(GeometricObject o1, GeometricObject o2) {
        return (o1.compareTo(o2) >= 0) ? o1 : o2;
    }

    public static double sumArea(GeometricObject[] a) {
        double sum = 0;
        for (GeometricObject o : a) {
            sum += o.getArea();
        }
        return sum;
    }
    /** Abstract method getArea */
    public abstract double getArea();

    /** Abstract method getPerimeter */
    public abstract double getPerimeter();
}

import javafx.scene.shape.Circle;

public class Circle2D  extends GeometricObject {

    private double x;
    private double y;
    private double radius;

    public Circle2D(Circle c) {
        this(c.getCenterX(), c.getCenterY(), c.getRadius());
    }
    public Circle2D(double x, double y, double radius) {
        this.x = x;
        this.y = y;
        this.radius = radius;
    }

    public Circle2D() {
        this(0, 0, 1);
    }

    public double getX() {
        return x;
    }

    public void setX(double x) {
        this.x = x;
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    @Override
    public double getArea() {
        return radius * radius * Math.PI;
    }

    @Override
    public double getPerimeter() {

        return 2 * radius * Math.PI;

    }



    public boolean contains(Circle2D circle2D) {
        double distance = getPoint().distance(circle2D.x, circle2D.y);

        if (distance <= Math.abs(this.radius - circle2D.radius)) {
            return true;
        } else {
            return false;
        }
    }

    public static boolean c1ContainsC2(Circle c1, Circle c2) {
        Circle2D cir1 = new Circle2D(c1);
        Circle2D cir2 =new Circle2D(c2);

        return cir1.contains(cir2);
    }

    public static boolean c1OverlapsC2(Circle c1, Circle c2) {
        Circle2D cir1 = new Circle2D(c1);
        Circle2D cir2 =new Circle2D(c2);

        if (cir1.contains(cir2) || cir2.contains(cir1)) return false;

        return cir1.overlaps(cir2);
    }

    public boolean overlaps(Circle2D circle2D) {
        double distance = getPoint().distance(circle2D.x, circle2D.y);

        if (distance  <= this.radius + circle2D.radius)
            return true;
        else
            return false;

    }

    private MyPoint getPoint() {
        return new MyPoint(this.x, this.y);
    }

    @Override
    public String toString() {
        return "Circle2D{" +
                "x=" + x +
                ", y=" + y +
                ", radius=" + radius +
                '}';
    }

    public boolean contains(double x, double y) {

        double distance = getPoint().distance(x, y);

        if (distance <= radius) return true;
        else return false;
    }
}

public class Exercise_05 {

    public static void main(String[] args) {

        Circle2D c1 = new Circle2D(0, 0, 5);
        Circle2D c2 = new Circle2D(0, 0, 2);
        Circle2D maxCircle =(Circle2D)GeometricObject.max(c1, c2);
        System.out.println("Circle 1: " + c1);
        System.out.println("Circle 2: " + c2);
        System.out.println("Max circle is: " + maxCircle);

        MyRectangle2D r1 = new MyRectangle2D(0, 0, 10, 5);
        MyRectangle2D r2 = new MyRectangle2D(0, 0, 10, 10);
        MyRectangle2D maxRectangle = (MyRectangle2D) GeometricObject.max(r1, r2);
        System.out.println("MyRec2 1: " + r1);
        System.out.println("MyRec2 2: " + r2);
        System.out.println("Max MyRec2 is: " + maxRectangle);


    }


}

1 comment :

  1. Thanks so much for all the hard work, super helpful. You went a bit overkill on this one, though. Using the 2D class rather than just simple shapes with areas is well beyond the scope of the exercise. It's only concerned with testing area, not location on a grid.

    ReplyDelete